HDU 4292 Food 多源多汇入门题
有F种食物和D种饮料,每种食物或饮料只能供有限次,且每个人只享用一种食物和一种饮料。现在有n个人,每个人都有自己喜欢的食物种类列表和饮料种类列表,问最多能使几个人同时享用到自己喜欢的食物和饮料。
邻接矩阵 DINIC 在定点数较多的时候比较慢。time 608 ms 。邻接表可以加速
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 #include <string> 7 #include <vector> 8 #include <set> 9 #include <map> 10 #include <stack> 11 #include <queue> 12 #include <sstream> 13 #include <iomanip> 14 using namespace std; 15 typedef long long LL; 16 const int INF = 0x4fffffff; 17 const double EXP = 1e-5; 18 const int MS = 205; 19 const int SIZE = 100005; 20 21 int edges[4*MS][4*MS]; 22 int level[4*MS]; 23 int que[6*MS]; 24 char str[MS]; 25 int qs,qe; 26 int n,f,d,cnt; 27 28 bool BFS() 29 { 30 memset(level,0xff,sizeof(level)); 31 level[0]=0; 32 qs=qe=0; 33 que[qe++]=0; 34 while(qs<qe) 35 { 36 int u=que[qs++]; 37 for(int v=0;v<=cnt;v++) 38 { 39 if(level[v]<0&&edges[u][v]>0) 40 { 41 level[v]=level[u]+1; 42 que[qe++]=v; 43 } 44 } 45 } 46 return level[cnt]>0; 47 } 48 49 int DFS(int u,int minv) 50 { 51 if(u==cnt) 52 return minv; 53 int t; 54 for(int v=0;v<=cnt;v++) 55 { 56 if(edges[u][v]>0&&level[v]==level[u]+1&&(t=DFS(v,min(minv,edges[u][v])))) 57 { 58 edges[u][v]-=t; 59 edges[v][u]+=t; 60 return t; 61 } 62 } 63 level[u]=0xff; 64 return 0; 65 } 66 67 int main() 68 { 69 while(scanf("%d%d%d",&n,&f,&d)!=EOF) 70 { 71 memset(edges,0,sizeof(edges)); 72 int w; 73 for(int i=1;i<=f;i++) 74 { 75 scanf("%d",&w); 76 edges[0][i]=w; 77 } 78 // 0 1--> f, f+1--->f+n, f+n+1 --> f+2*n f+2*n+1-->f+2*n+d f+2*n+d+1; 79 for(int i=1;i<=n;i++) 80 edges[f+i][f+n+i]=1; 81 cnt=f+2*n+d+1; 82 for(int i=1;i<=d;i++) 83 { 84 scanf("%d",&w); 85 edges[f+2*n+i][cnt]=w; 86 } 87 for(int i=1;i<=n;i++) 88 { 89 scanf("%s",str); 90 for(int j=0;j<f;j++) 91 { 92 if(str[j]=='Y') 93 { 94 edges[j+1][f+i]=1; 95 } 96 } 97 } 98 99 for(int i=1;i<=n;i++) 100 { 101 scanf("%s",str); 102 for(int j=0;j<d;j++) 103 { 104 if(str[j]=='Y') 105 { 106 edges[f+n+i][f+2*n+j+1]=1; 107 } 108 } 109 } 110 int ans=0; 111 int t; 112 while(BFS()) 113 { 114 while(t=DFS(0,INF)) 115 { 116 ans+=t; 117 } 118 } 119 printf("%d\n",ans); 120 } 121 return 0; 122 }
time 124ms
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 #include <string> 7 #include <vector> 8 #include <set> 9 #include <map> 10 #include <stack> 11 #include <queue> 12 #include <sstream> 13 #include <iomanip> 14 using namespace std; 15 typedef long long LL; 16 const int INF = 0x4fffffff; 17 const double EXP = 1e-5; 18 const int MS = 805; 19 const int SIZE = 200005; 20 21 22 struct edge 23 { 24 int v,w,next; 25 }edges[SIZE]; 26 27 int head[MS]; 28 int level[MS]; 29 int que[MS]; 30 int qs,qe,cnt; 31 int n,f,d; 32 int src,des; 33 34 void add(int u,int v,int w) 35 { 36 edges[cnt].v=v;edges[cnt].w=w;edges[cnt].next=head[u];head[u]=cnt++; 37 edges[cnt].v=u;edges[cnt].w=0;edges[cnt].next=head[v];head[v]=cnt++; 38 } 39 40 int BFS() 41 { 42 memset(level,-1,sizeof(level)); 43 qs=qe=0; 44 level[src]=0; 45 que[qe++]=src; 46 while(qs<qe) 47 { 48 int u=que[qs++]; 49 for(int i=head[u];i!=-1;i=edges[i].next) 50 { 51 int v=edges[i].v; 52 if(level[v]<0&&edges[i].w>0) 53 { 54 level[v]=level[u]+1; 55 que[qe++]=v; 56 } 57 } 58 } 59 return level[des]>0; 60 } 61 62 int DFS(int u,int minv) 63 { 64 if(u==des) 65 return minv; 66 int t; 67 for(int i=head[u];i!=-1;i=edges[i].next) 68 { 69 int v=edges[i].v; 70 if(edges[i].w>0&&level[v]==level[u]+1&&(t=DFS(v,min(edges[i].w,minv)))) 71 { 72 edges[i].w-=t; 73 edges[i^1].w+=t; 74 return t; 75 } 76 } 77 level[u]=-1; // 从u出发无法找到argument 78 return 0; 79 } 80 81 82 int main() 83 { 84 while(scanf("%d%d%d",&n,&f,&d)!=EOF) 85 { 86 memset(head,-1,sizeof(head)); 87 int w; 88 char str[MS]; 89 des=f+2*n+d+1; 90 src=cnt=0; 91 for(int i=1;i<=f;i++) 92 { 93 scanf("%d",&w); 94 add(src,i,w); 95 } 96 // 0 1--> f, f+1--->f+n, f+n+1 --> f+2*n f+2*n+1-->f+2*n+d f+2*n+d+1; 97 for(int i=1;i<=n;i++) 98 add(f+i,f+n+i,1); 99 for(int i=1;i<=d;i++) 100 { 101 scanf("%d",&w); 102 add(f+2*n+i,des,w); 103 } 104 for(int i=1;i<=n;i++) 105 { 106 scanf("%s",str); 107 for(int j=0;j<f;j++) 108 { 109 if(str[j]=='Y') 110 { 111 add(j+1,f+i,1); 112 } 113 } 114 } 115 116 for(int i=1;i<=n;i++) 117 { 118 scanf("%s",str); 119 for(int j=0;j<d;j++) 120 { 121 if(str[j]=='Y') 122 { 123 add(f+n+i,f+2*n+j+1,1); 124 } 125 } 126 } 127 int ans=0; 128 int t; 129 while(BFS()) 130 { 131 while(t=DFS(src,INF)) 132 { 133 ans+=t; 134 } 135 } 136 printf("%d\n",ans); 137 } 138 return 0; 139 }
这题和poj 3281基本上是一样的。链接:Dining
Dining是每种食物和饮料只能分配给一个人。所以可以把容量看成1. 可以看成是一样的题目。 DINIC() 0ms;
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 #include <string> 7 #include <vector> 8 #include <set> 9 #include <map> 10 #include <stack> 11 #include <queue> 12 #include <sstream> 13 #include <iomanip> 14 using namespace std; 15 typedef long long LL; 16 const int INF = 0x4fffffff; 17 const double EXP = 1e-5; 18 const int MS = 805; 19 const int SIZE = 200005; 20 21 22 struct edge 23 { 24 int v,w,next; 25 }edges[SIZE]; 26 27 int head[MS]; 28 int level[MS]; 29 int que[MS]; 30 int qs,qe,cnt; 31 int n,f,d; 32 int src,des; 33 34 void add(int u,int v,int w) 35 { 36 edges[cnt].v=v;edges[cnt].w=w;edges[cnt].next=head[u];head[u]=cnt++; 37 edges[cnt].v=u;edges[cnt].w=0;edges[cnt].next=head[v];head[v]=cnt++; 38 } 39 40 int BFS() 41 { 42 memset(level,-1,sizeof(level)); 43 qs=qe=0; 44 level[src]=0; 45 que[qe++]=src; 46 while(qs<qe) 47 { 48 int u=que[qs++]; 49 for(int i=head[u];i!=-1;i=edges[i].next) 50 { 51 int v=edges[i].v; 52 if(level[v]<0&&edges[i].w>0) 53 { 54 level[v]=level[u]+1; 55 que[qe++]=v; 56 } 57 } 58 } 59 return level[des]>0; 60 } 61 62 int DFS(int u,int minv) 63 { 64 if(u==des) 65 return minv; 66 int t; 67 for(int i=head[u];i!=-1;i=edges[i].next) 68 { 69 int v=edges[i].v; 70 if(edges[i].w>0&&level[v]==level[u]+1&&(t=DFS(v,min(edges[i].w,minv)))) 71 { 72 edges[i].w-=t; 73 edges[i^1].w+=t; 74 return t; 75 } 76 } 77 level[u]=-1; // 从u出发无法找到argument 78 return 0; 79 } 80 81 82 int main() 83 { 84 while(scanf("%d%d%d",&n,&f,&d)!=EOF) 85 { 86 memset(head,-1,sizeof(head)); 87 int w; 88 char str[MS]; 89 des=f+2*n+d+1; 90 src=cnt=0; 91 for(int i=1;i<=f;i++) 92 add(src,i,1); 93 // 0 1--> f, f+1--->f+n, f+n+1 --> f+2*n f+2*n+1-->f+2*n+d f+2*n+d+1; 94 for(int i=1;i<=n;i++) 95 add(f+i,f+n+i,1); 96 for(int i=1;i<=d;i++) 97 add(f+2*n+i,des,1); 98 int fsum,dsum,t; 99 for(int i=1;i<=n;i++) 100 { 101 scanf("%d%d",&fsum,&dsum); 102 for(int j=1;j<=fsum;j++) 103 { 104 scanf("%d",&t); 105 add(t,f+i,1); 106 } 107 for(int j=1;j<=dsum;j++) 108 { 109 scanf("%d",&t); 110 add(f+n+i,f+2*n+t,1); 111 } 112 } 113 int ans=0; 114 while(BFS()) 115 { 116 while(t=DFS(src,INF)) 117 { 118 ans+=t; 119 } 120 } 121 printf("%d\n",ans); 122 } 123 return 0; 124 }