POJ-3281Dining 最大流

xiaoxiao2021-02-28  19

这题是挑战程序设计竞赛的例题,因为师兄讲了所以就补了

做法:

建图的方法是:加一个源点和汇点,讲饮料或食物分别连向源点、汇点,对于每一头牛,把它和它喜欢的食物和饮料连边,由于每一头牛在考虑的时候都是只能被一个边流入和流出(因为每一头牛都是只能吃一个食物喝一个饮料),所以把牛拆点(假如拆成牛1,牛2),就在牛1和牛2之间连一条边。然后源点到汇点跑一遍dinic就可以了。

代码:

#pragma GCC optimize(2) //#include <bits/stdc++.h> #include<iostream> #include<cstdio> #include<queue> #include<cstring> #ifdef DEBUG # pragma GCC optimize(0) #endif // DEBUG #define mem(x,y) memset(x,y,sizeof(x)) #define startcoding ios::sync_with_stdio(false);\ cin.tie(0); using namespace std;namespace NYAM{ /*************************************************/ typedef long long ll; typedef unsigned long long ull; typedef long double ld; /**************************************************/ const int maxm=3e5+5; const int inf=0x3f3f3f3f; const int maxn=505; int head[maxn]; struct edge { int cap,to,next; }e[maxm]; int dis[maxn]; int s,t,ecnt; void ins(int u,int v,int cap) { e[ecnt].to=v; e[ecnt].next=head[u]; e[ecnt].cap=cap; head[u]=ecnt++; e[ecnt].to=u; e[ecnt].next=head[v]; e[ecnt].cap=0; head[v]=ecnt++; } int bfs() { mem(dis,-1); queue<int>q; dis[s]=0; q.push(s); while(!q.empty()) { int u=q.front(); q.pop(); for(int i=head[u];i>=0;i=e[i].next) { int v=e[i].to; if(e[i].cap>0&&dis[v]==-1) { dis[v]=dis[u]+1; q.push(v); } } } return dis[t]!=-1; } int dfs(int u,int f) { int tmp; if(u==t) return f; for(int i=head[u];i>=0;i=e[i].next) { int v=e[i].to; if(e[i].cap>0&&dis[v]==dis[u]+1) { tmp=dfs(v,min(f,e[i].cap)); if(tmp>0) { e[i].cap-=tmp; e[i^1].cap+=tmp; return tmp; } } } dis[u]=-1; return 0; } int dinic() { int ans=0; while(bfs()) { //cout<<"aha"<<endl; int tmp=dfs(s,inf); while(tmp>0) { ans+=tmp; tmp=dfs(s,inf); } } return ans; } void main() { startcoding t=504; int n,f,d; while(cin>>n>>f>>d) { mem(head,-1); ecnt=0; for(int i=1;i<=f;i++) ins(s,i,1); //for(int i=1;i<=n;i++) ins(f+i,f+n+i,1); //对牛拆点 for(int i=1;i<=d;i++) ins(f+2*n+i,t,1); for(int i=1;i<=n;i++) { ins(f+i,f+n+i,1); int F,D,x; cin>>F>>D; for(int j=1;j<=F;j++) { cin>>x; ins(x,f+i,1); } for(int j=1;j<=D;j++) { cin>>x; ins(f+n+i,f+2*n+x,1); } } cout<<dinic()<<endl; } return; } } int main(){ #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); #endif //ONLINE_JUDGE NYAM::main(); exit(0); }
转载请注明原文地址: https://www.6miu.com/read-2629616.html

最新回复(0)