网络流/poj1698 Alice's Chance
题意
有N部电影,分别可以在一个星期的几天拍摄,并可以拍W个星期,Alice可以有D个星期拍这部电影,一天只能拍一部电影。问Alice能否拍完所有电影
分析
这题直接把每天看成一个点,每部电影也看成一个点,然后源点与电影连接,容量为要求天数,电影与能工作的那些天连容量为1的边,每天再连一条容量为1 的边到汇,最大流为所有要求天数之和就是Yes
Accepted Code
1 /* 2 PROBLEM:poj1698 3 AUTHER:Rinyo 4 MEMO:网络流 5 */ 6 #include<cstdio> 7 #include<queue> 8 #include<cstring> 9 using namespace std; 10 int a[372][10],map[372][372],dis[372]; 11 int s,t; 12 int bfs() 13 { 14 queue<int> q; 15 memset(dis,-1,sizeof(dis)); 16 dis[t]=0; 17 q.push(t); 18 while (!q.empty()) 19 { 20 int k=q.front(); 21 q.pop(); 22 for (int i=0;i<372;i++) 23 { 24 if (dis[i]==-1 && map[i][k]) 25 { 26 dis[i]=dis[k]+1; 27 q.push(i); 28 } 29 } 30 if (k==s) return 1; 31 } 32 return 0; 33 } 34 35 int dfs(int now,int v) 36 { 37 if (now==371) return v; 38 int tmp=v; 39 for (int i=0;i<372 && tmp;i++) 40 { 41 if (dis[i]+1==dis[now] && map[now][i]) 42 { 43 int t=dfs(i,min(map[now][i],tmp)); 44 map[now][i]-=t; 45 map[i][now]+=t; 46 tmp-=t; 47 } 48 } 49 return v-tmp; 50 } 51 int main() 52 { 53 freopen("in.txt","r",stdin); 54 int cnt,ans; 55 scanf("%d",&cnt); 56 while (cnt--) 57 { 58 ans=s=0;t=371; 59 memset(map,0,sizeof(map)); 60 memset(a,0,sizeof(a)); 61 int n; 62 scanf("%d",&n); 63 for (int i=1;i<=n;i++) 64 { 65 for (int j=1;j<=9;j++) scanf("%d",&a[i][j]); 66 ans+=a[i][8]; 67 } 68 for (int i=1;i<=n;i++) 69 { 70 map[0][i+350]=a[i][8]; 71 for (int j=1;j<=7;j++) 72 { 73 if (a[i][j]) 74 { 75 for (int k=0;k<a[i][9];k++) map[i+350][j+k*7]=1; 76 } 77 } 78 } 79 for (int i=1;i<=350;i++) map[i][371]=1; 80 int maxflow=0; 81 while (bfs()) maxflow+=dfs(0,2147483647); 82 if (ans==maxflow) printf("Yes\n"); 83 else printf("No\n"); 84 } 85 return 0; 86 }