POJ 1698Alice's Chance(二分匹配解)

构图啊,万恶的构图,下次要注意……

这题用最大流过了,觉得匹配也可以,就是把需要多次匹配的点集的每个点按其允许匹配次数拆分,拆完就成最基本的二分匹配了

 

#include<iostream> #define N 1001 using namespace std; int n,day,sum,map[N][600],vis[N],match[N]; void getmap() { int i,j,k,p,begin; scanf("%d",&n); memset(map,0,sizeof(map)); int max=-1; sum=0; begin=1; for(i=1;i<=n;i++) { int count=0; int a[8]; for(j=1;j<=7;j++) scanf("%d",&a[j]); int d,w; scanf("%d%d",&d,&w); sum+=d; if(w>max) max=w; for(j=begin; j<begin+d; j++) { for(k=1; k<=7; k++) if( a[k] == 1 ) for(p=0; p<w; p++) map[j][k+p*7] = 1; } begin+=d; } day=max*7; //max,周的最大值 } int dfs(int k) { int i; for(i=1;i<=day;i++) { if(map[k][i] && !vis[i]) //第k部电影,第i天 { vis[i]=1; if( !match[i] || dfs(match[i]) ) //第i天没被占用,或者占用第i天的电影可以找到其他档期 { match[i]=k; return 1; } } } return 0; } int main() { int i,text; scanf("%d",&text); while(text--) { getmap(); memset(match,0,sizeof(match)); int cnt=0; for(i=1;i<=sum;i++) { memset(vis,0,sizeof(vis)); if( dfs(i) ) cnt++; } if(cnt>=sum) printf("Yes/n"); else printf("No/n"); } return 0; }  

你可能感兴趣的:(POJ 1698Alice's Chance(二分匹配解))