POJ 1698 Alice's Chance(网络流+构图)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ 1698 Alice's Chance(网络流+构图)相关的知识,希望对你有一定的参考价值。

题目链接:http://poj.org/problem?id=1698

题目:

Description

Alice, a charming girl, have been dreaming of being a movie star for long. Her chances will come now, for several filmmaking companies invite her to play the chief role in their new films. Unfortunately, all these companies will start making the films at the same time, and the greedy Alice doesn‘t want to miss any of them!! You are asked to tell her whether she can act in all the films. 

As for a film, 
  1. it will be made ONLY on some fixed days in a week, i.e., Alice can only work for the film on these days; 
  2. Alice should work for it at least for specified number of days; 
  3. the film MUST be finished before a prearranged deadline.

For example, assuming a film can be made only on Monday, Wednesday and Saturday; Alice should work for the film at least for 4 days; and it must be finished within 3 weeks. In this case she can work for the film on Monday of the first week, on Monday and Saturday of the second week, and on Monday of the third week. 

Notice that on a single day Alice can work on at most ONE film. 

Input

The first line of the input contains a single integer T (1 <= T <= 20), the number of test cases. Then T cases follow. Each test case begins with a single line containing an integer N (1 <= N <= 20), the number of films. Each of the following n lines is in the form of "F1 F2 F3 F4 F5 F6 F7 D W". Fi (1 <= i <= 7) is 1 or 0, representing whether the film can be made on the i-th day in a week (a week starts on Sunday): 1 means that the film can be made on this day, while 0 means the opposite. Both D (1 <= D <= 50) and W (1 <= W <= 50) are integers, and Alice should go to the film for D days and the film must be finished in W weeks.

Output

For each test case print a single line, ‘Yes‘ if Alice can attend all the films, otherwise ‘No‘.

Sample Input

2
2
0 1 0 1 0 1 0 9 3
0 1 1 1 0 0 0 6 4
2
0 1 0 1 0 1 0 9 4
0 1 1 1 0 0 0 6 2

Sample Output

Yes
No
题意:Alice去演n部电影,每部电影只能在每个星期的某几天演,需要演d天,截止星期为w。问Alice能否把这n部电影都演完。
题解:挺简单的一道题。创建一个超级源点和汇点,源点和每部电影连接,容量为电影需要演的天数;每部电影和可以演的日期连接,容量为1;350天全部和超级汇点连接,容量为1。
记得日期由星期都转换成天(最多50个星期,所以最多50*7=350天),注意答案的大小写...
 1 //POJ 1698
 2 #include <queue>
 3 #include <cstdio>
 4 #include <cstring>
 5 #include <iostream>
 6 #include <algorithm>
 7 using namespace std;
 8 
 9 const int N=444;
10 const int M=2*N*N;
11 const int INF=0x3f3f3f3f;
12 int s,t,cnt;
13 int Head[N],Depth[N],cur[N];
14 int Next[M],V[M],W[M];
15 
16 void init(){
17     cnt=-1;
18     memset(Head,-1,sizeof(Head));
19     memset(Next,-1,sizeof(Next));
20 }
21 
22 void add_edge(int u,int v,int w){
23     cnt++;Next[cnt]=Head[u];V[cnt]=v;W[cnt]=w;Head[u]=cnt;
24     cnt++;Next[cnt]=Head[v];V[cnt]=u;W[cnt]=0;Head[v]=cnt;
25 }
26 
27 bool bfs(){
28     queue <int> Q;
29     while(!Q.empty()) Q.pop();
30     memset(Depth,0,sizeof(Depth));
31     Depth[s]=1;
32     Q.push(s);
33     while(!Q.empty()){
34         int u=Q.front();Q.pop();
35         for(int i=Head[u];i!=-1;i=Next[i]){
36             if((W[i]>0)&&(Depth[V[i]]==0)){
37                 Depth[V[i]]=Depth[u]+1;
38                 Q.push(V[i]);
39             }
40         }
41     }
42     if(Depth[t]==0) return 0;
43     return 1;
44 }
45 
46 int dfs(int u,int dist){
47     if(u==t) return dist;
48     for(int& i=cur[u];i!=-1;i=Next[i]){
49         if((Depth[V[i]]==Depth[u]+1)&&W[i]!=0){
50             int di=dfs(V[i],min(dist,W[i]));
51             if(di>0){
52                 W[i]-=di;
53                 W[i^1]+=di;
54                 return di;
55             }
56         }
57     }
58     return 0;
59 }
60 
61 int Dinic(){
62     int ans=0;
63     while(bfs()){
64         for(int i=0;i<=371;i++) cur[i]=Head[i];
65         while(int d=dfs(s,INF)) ans+=d;
66     }
67     return ans;
68 }
69 
70 int main(){
71     int T,n,D,W;
72     scanf("%d",&T);
73     while(T--){
74         int day[8],sum=0;
75         scanf("%d",&n);
76         init();
77         s=0;t=371;
78         for(int i=1;i<=n;i++){
79             for(int j=1;j<=7;j++) scanf("%d",&day[j]);
80             scanf("%d %d",&D,&W);
81             sum+=D;
82             add_edge(s,350+i,D);
83             for(int j=1;j<=W;j++){
84                 for(int k=1;k<=7;k++) {if(day[k]>0) add_edge(350+i,(j-1)*7+k,1);}
85             }
86         }
87         for(int i=1;i<=350;i++) add_edge(i,t,1);
88         if(sum==Dinic()) printf("Yes\n");
89         else printf("No\n");
90     }
91 
92     return 0;
93 }

 

 

以上是关于POJ 1698 Alice's Chance(网络流+构图)的主要内容,如果未能解决你的问题,请参考以下文章

POJ 1698 Alice&#39;s Chance(最大流+拆点)

POJ 1698 图论之网络流

hdu 4122 Alice's mooncake shop

hdu3544 Alice's Game

HDOJ4122 Alice's mooncake shop

Alice's birthday