POJ 3281 Dining & HDU 4292 Food【最大流】

来源:互联网 发布:大华网络摄像机 复位 编辑:程序博客网 时间:2024/06/10 18:11

这两题基本一样

POJ 3281

链接

题意:

有N个牛,F个食物,D个饮料,每个牛只吃其中若干种食物和饮料,规定每个牛要么不吃,要么食物和饮料各吃一种,各种食物和饮料都只有一个。求最多多少牛能得到满足(吃食物+饮料)

输入格式:

给牛的数量N,食物数量F,饮料数量D

接下来的N行(1到N号牛),然后TF,TD,接下来TF个食物编号,TD个饮料编号,表示 i 号牛只吃这TF个食物,TD个饮料

建图:

首先知道要把牛分点,分为牛1,牛2,如果不分则建图为

食物->牛->饮料,若牛选了食物A,饮料B,则若食物C,饮料D也跟牛有边,则被算法认为是增广路,但这并不满足每牛只能吃一种饮料和食物。

所以要变为:

源点S->食物->牛1->牛2->饮料->汇点T,所有容量为1。

#include <cstdio>#include <cmath>#include <cstring>#include <string>#include <set>#include <map>#include <stack>#include <queue>#include <vector>#include <iostream>#include <algorithm>using namespace std;#define ll long long#define eps 10^(-6)#define Q_CIN ios::sync_with_stdio(false)#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )#define FOR( i , a , b ) for ( int i = a ; i <= b ; ++ i )#define CLR( a , x ) memset ( a , x , sizeof (a) )#define RE freopen("1.in","r",stdin);#define WE freopen("1.out","w",stdout);#define MOD 10009#define NMAX 10002#define min(a,b) ((a)>(b)?(b):(a))#define max(a,b) ((a)<(b)?(b):(a))const int inf=0x3f3f3f3f;const int maxn=2*100+105+105;int ss,tt;int cap[maxn][maxn],dis[maxn];int bfs(int s,int t){    queue<int>q;    q.push(s);    CLR(dis,-1);    dis[s]=0;    while(!q.empty()){        int tmp=q.front();q.pop();        FOR(i,s,t){            if(dis[i]<0&&cap[tmp][i]){                dis[i]=dis[tmp]+1;                q.push(i);            }        }    }    if(dis[t]>0) return 1;    return 0;}int dfs(int s,int t,int low){    int flow;    if(s==t)   return low;    FOR(i,ss,tt){   //ss->tt        if(cap[s][i]           &&(dis[i]==dis[s]+1)           &&(flow=dfs(i,t,min(cap[s][i],low)))){            cap[s][i]-=flow;            cap[i][s]+=flow;            return flow;        }    }    return 0;}int main(){//    freopen("1.in","r",stdin);    int n,f,d;    int tf,td,tx;    while(cin>>n>>f>>d){        ss=0,tt=2*n+f+d+1;        CLR(cap,0);        FOR(i,1,n){            cin>>tf>>td;            while(tf--){                cin>>tx;                tx+=2*n;                cap[ss][tx]=1;    //src to food                cap[tx][i]=1;       //food to cow            }            while(td--){                cin>>tx;                tx+=2*n+f;                cap[tx][tt]=1;      //drink to end                cap[i+n][tx]=1;   //cow to drink            }            cap[i][i+n]=1;      //cow1 to cow2        }        int ans=0;        while(bfs(ss,tt)){            ans+=dfs(ss,tt,inf);        }        cout<<ans<<endl;    }}


HDU 4292 Food
此题邻接矩阵Dinic过不了,邻接表600MS,在DFS中加个//dis[u]=-1;就100MS!
#include <cstdio>#include <cmath>#include <cstring>#include <string>#include <set>#include <map>#include <stack>#include <queue>#include <vector>#include <iostream>#include <algorithm>using namespace std;#define ll long long#define eps 10^(-6)#define Q_CIN ios::sync_with_stdio(false);#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )#define FOR( i , a , b ) for ( int i = a ; i <= b ; ++ i )#define CLR( a , x ) memset ( a , x , sizeof (a) );#define RE freopen("1.in","r",stdin);#define WE freopen("1.out","w",stdout);#define MOD 10009#define debug(x) cout<<#x<<":"<<(x)<<endl;#define sc(x) scanf("%d",&x);#define lson i<<1,l,m#define rson i<<1|1,m+1,rconst int maxn=805;const int maxm=200005;const int inf=0x3f3f3f3f;int dis[maxn];int ss,tt;int cnt;int head[maxn],q[maxn];struct Edge{    int v,w,next;}edge[maxm*2];void addEdge(int u,int v,int w){    edge[cnt].v=v,edge[cnt].w=w,edge[cnt].next=head[u];head[u]=cnt++;    edge[cnt].v=u,edge[cnt].w=0,edge[cnt].next=head[v];head[v]=cnt++;}void init(){    CLR(head,-1);    cnt=0;}int bfs(){    queue<int>q;    q.push(ss);    CLR(dis,-1);    dis[ss]=0;    while(!q.empty())    {        int u=q.front();q.pop();        for(int i=head[u];i!=-1;i=edge[i].next)        {            int v=edge[i].v;            if(edge[i].w&&dis[v]<0)            {                dis[v]=dis[u]+1;                q.push(v);            }        }    }    return dis[tt]>0;}//int bfs() //居然比STL慢10多ms//{//    int first=0,tail=0;//    q[tail++]=ss;//    CLR(dis,-1);//    dis[ss]=0;//    while(first<tail)//    {//        int u=q[first++];//        for(int i=head[u];i!=-1;i=edge[i].next)//        {//            int v=edge[i].v;//            if(edge[i].w && dis[v]<0)//            {//                dis[v]=dis[u]+1;//                q[tail++]=v;//            }//        }//    }//    return dis[tt]>0;//}int dfs(int u,int low){    int flow;    if(u==tt)   return low;    for(int i=head[u];i!=-1;i=edge[i].next)    {        if(edge[i].w        && (dis[edge[i].v]==dis[u]+1)        && (flow = dfs(edge[i].v,min(low,edge[i].w)))){            edge[i].w-=flow;            edge[i^1].w+=flow;            return flow;        }    }    dis[u]=-1;    return 0;}int maxFlow(){    int ans=0,tans;    while(bfs())        while(tans=dfs(ss,inf))            ans+=tans;    return ans;}int main(){//    RE    int n,f,d,tw;    char s1[205];    char ch;    while(scanf("%d%d%d",&n,&f,&d)!=EOF)    {        init();        ss=0,tt=2*n+f+d+1;        FOR(i,1,f)  //food:1-f        {            scanf("%d",&tw);            addEdge(ss,i,tw);        }        FOR(i,1,d)  //drink:1+f+2*n ~ d+f+2*n        {            scanf("%d",&tw);            addEdge(i+f+2*n,tt,tw);        }        FOR(i,1,n)        {            scanf("%s",s1);            FOR(j,1,f)            {                if(s1[j-1]=='Y'){                    addEdge(j,f+i,1);   //food:1~n people1:f+1~f+n                }            }            addEdge(i+f,i+f+n,1);        }        FOR(i,1,n)        {            scanf("%s",s1);            FOR(j,1,d)            {                if(s1[j-1]=='Y')                    addEdge(i+f+n,j+f+2*n,1);   //people2:f+n+1~f+n+n drink:f+d+2*n+1~f+d+2*n+d            }        }        printf("%d\n",maxFlow());    }    return 0;}


0 0
原创粉丝点击