我爱崔老师系列之 最大流 拆点 EK poj3281 dining"/>
我爱崔老师系列之 最大流 拆点 EK poj3281 dining
题目连接:=3281
有人所用邻接矩阵会超时。。。然后。。。哥笑了~(*^__^*) 嘻嘻……
其实这题我觉得这不超时
这题一开始崔老师说把牛放中间我的意思是把人放在最前面,因为如果放在中间1头牛3物三水的话答案就会错误,但是如果把人放在前面感觉又会不大对= =。。然后崔老师就神一般的回答说拆点!顿时天亮了= =。。。其实我真心不知道拆点是神马。。。比赛有一道拆点我枚举匹配一下就过了。。虽然也是拆点的思想= =。。。
总之拆点就是为了先吃每个点的出度唯一(个人理解)而做的重复两次操作。博客的上一个acm computer其实就是拆点。。。但是没人点出来。。。还是崔老师是文化人毕竟出去学习过啊。。。在此给崔神跪了~。。。
代码
View Code1 #include <stdio.h> 2 #include <string.h> 3 #include <iostream> 4 #include <queue> 5 #define maxn 100000 6 using namespace std; 7 struct node 8 { 9 int fod[105],drk[105],f,d; 10 }cow[105]; 11 int cap[405][405]; 12 int ek(int n) 13 { 14 int f = 0,i; 15 int flow[405][405] = {0}; 16 memset(flow,0,sizeof(flow)); 17 int temp[405],pre[405]; 18 memset(pre,0,sizeof(pre)); 19 20 queue<int>q; 21 for(;;) 22 { 23 q.push(0); 24 memset(temp,0,sizeof(temp)); 25 temp[0] = maxn; 26 q.push(0); 27 while(!q.empty()) 28 { 29 int u = q.front(); 30 q.pop(); 31 for(i = 0; i <= n;i++) 32 { 33 if(!temp[i] && cap[u][i]>flow[u][i]) 34 { 35 q.push(i); 36 pre[i]= u; 37 temp[i] = min(temp[u],cap[u][i]-flow[u][i]); 38 } 39 } 40 } 41 if(temp[n] == 0) 42 break; 43 44 for(i = n;i != 0;i = pre[i]) 45 { 46 flow[pre[i]][i] += temp[n]; 47 flow[i][pre[i]] -= temp[n]; 48 } 49 f += temp[n]; 50 //printf("%d****\n",temp[n]); 51 } 52 return f; 53 } 54 int main() 55 { 56 int m,n,t,i,j,k; 57 int u; 58 int val; 59 while(~scanf("%d %d %d",&m,&n,&t)) 60 { 61 memset(cap,0,sizeof(cap)); 62 for(i = 1;i <= m;i++) 63 { 64 scanf("%d %d",&cow[i].f,&cow[i].d); 65 for(j = 1;j <= cow[i].f;j++) 66 { 67 68 scanf("%d",&val); 69 cap[val][n+i] = 1; 70 } 71 for(j = 1;j <= cow[i].d;j++) 72 { 73 scanf("%d",&val); 74 cap[n+m+i][n+m+m+val] = 1; 75 } 76 } 77 for(i = 1;i <= m;i++) 78 cap[n+i][n+m+i] = 1; 79 for(i = 1;i <= n;i++) 80 cap[0][i] = 1; 81 for(i = 1;i <= t;i++) 82 cap[n+m+m+i][n+2*m+t+1] = 1; 83 int res = ek(2*m+t+n+1); 84 cout<<res<<endl; 85 } 86 return 0; 87 }
转载于:.html
更多推荐
我爱崔老师系列之 最大流 拆点 EK poj3281 dining
发布评论