自己的构图和搜的题解不太一样,果然构图都不太一样(想法比较奇葩。。。。,建议另寻题解,但是有个提醒,图论看了构图也就没有含义了,因为敲代码就是那几分钟的事情,构图却要想很久)
把一星期拆成7个点,把每部电影看成一个点,增加一个源点,和每天连在一起,容量为有该天数的最大星期(比如第一部电影和第三部电影,两者都能在星期一拍,但是第一部的deadline是第五个星期,另一部呢,是第3个星期,那么容量就是5)
然后每部电影相应的天数连向自己,容量为deadline,最后每部电影和t连在一起,容量为需要天数
附上代码
#include<stdio.h> #include<string.h> #include<queue> #define INF 1<<25 #define val 50 using namespace std; int n,m,pre[val],cap[val][val],flow[val]; char week[8],s,t,data[8],day; void create_link(); int maxflow(); inline int Min(int a,int b) { return a<b?a:b; } int main() { int t,ans; for(scanf("%d",&t);t;t--) { day=0; scanf("%d",&n); create_link(); ans=maxflow(); // printf("ANS:%d\n",ans); if(ans==day) printf("Yes\n"); else printf("No\n"); } return 0; } void create_link() { int i,j,a,b,max; s=max=0; t=8+n; memset(data,0,sizeof(data)); memset(cap,0,sizeof(cap)); for(i=1;i<=n;i++) { for(j=1;j<=7;j++) scanf("%d",&week[j]); scanf("%d %d",&a,&b); for(j=1;j<=7;j++) { if(week[j]==1) { if(b>data[j]) data[j]=b; cap[j][i+7]=b; } } if(b>max) max=b; cap[7+i][t]=a; day+=a; } for(i=1;i<=7;i++) cap[s][i]=data[i]; /* for(i=0;i<=t;i++) { for(j=0;j<=t;j++) printf("%d ",cap[i][j]); putchar('\n'); }*/ } int maxflow() { bool bfs(); int sum=0,x; while(1) { if(bfs()==false) break; sum+=flow[t]; x=t; // printf("FIND!!! flow:%d \n",flow[t]); while(x!=pre[x]) { // printf("X:%d pre:%d\n",x,pre[x]); cap[pre[x]][x]-=flow[t]; cap[x][pre[x]]+=flow[t]; x=pre[x]; } // printf("\n_________________________\n"); } return sum; } bool bfs() { int i,x; queue<int> q; q.push(0); memset(pre,-1,sizeof(pre)); pre[0]=0; for(i=s;i<=t;i++) flow[i]=INF; while(!q.empty()) { x=q.front(); q.pop(); if(x==t) break; for(i=0;i<=t;i++) { if(cap[x][i]==0||pre[i]!=-1) continue; pre[i]=x; flow[i]=Min(flow[x],cap[x][i]); q.push(i); } } if(pre[t]==-1) return false; else return true; }