额。。很难得自己终于会构图了。。但是构了个费用流。。。一会看看能不能过。。
题意:
n个电影需要演,每个电影都有特定的日期可以拍摄,每个电影也都要在特定的星期数里完成,而且也有其必须要演的天数。小Alice同时做它们,问能不能最后都完成他们(周数做多的那个完成时,所有的电影都完成了)。
题解:
每个电影都建点,每天都建点(建max周数 *7个点),源点到每个电影点建边 c为这个电影所要演的天数。每个电影对他能演的天数建边,c=1。每天对汇点建边,c=1。这样最大流过后如果流量等于总天数,那么Yes,否则No。
#include<stdio.h>
#include<string.h>
#define nMax 100000
#define MX 100000000
int que[nMax*5],n,T,list[nMax],dist[nMax],vs,vt,cas,k;
struct Egde{
int u,v,f,next;
}eg[1000000];
void add(int u,int v,int f){
eg[k].u=u;eg[k].v=v;eg[k].next=list[u];eg[k].f=f;list[u]=k++;
eg[k].u=v;eg[k].v=u;eg[k].next=list[v];eg[k].f=0;list[v]=k++;
}
int dinic(int s,int t){
int ans=0;
while(true){
int head,tail,id,i;
head=tail=0;
que[tail++]=s;
memset(dist,-1,sizeof(dist));
dist[s]=0;
while(head<tail){
id=list[que[head++]];
while(id!=-1){
if(eg[id].f>0&&dist[eg[id].v]==-1){
dist[eg[id].v]=dist[eg[id].u]+1;
que[tail++]=eg[id].v;
if(eg[id].v==t){
head=tail;
break;
}
}
id=eg[id].next;
}
}
if(dist[t]==-1)
break;
id=s,tail=0;
while(true){
if(id==t){
int flow=MX,fir;
for(i=0;i<tail;i++)
if(eg[que[i]].f<flow){
fir=i;
flow=eg[que[i]].f;
}
for(i=0;i<tail;i++)
eg[que[i]].f-=flow,eg[que[i]^1].f+=flow;
ans+=flow;
tail=fir;
id=eg[que[fir]].u;
}
id=list[id];
while(id!=-1){
if(eg[id].f>0&&dist[eg[id].u]+1==dist[eg[id].v])
break;
id=eg[id].next;
}
if(id!=-1){
que[tail++]=id;
id=eg[id].v;
}
else{
if(tail==0)
break;
dist[eg[que[tail-1]].v]=-1;
id=eg[que[--tail]].u;
}
}
}
return ans;
}
struct Week{
int f[7],d,w;
}week[30];
int main(){
scanf("%d",&T);
while(T--){
memset(list,-1,sizeof(list));
scanf("%d",&n);
int D=0;
int maxw=0;
for(int i=0;i<n;i++){
for(int j=0;j<7;j++){
scanf("%d",&week[i].f[j]);
}
scanf("%d",&week[i].d);
D+=week[i].d;
scanf("%d",&week[i].w);
if(week[i].w>maxw){
maxw=week[i].w;
}
}
vs=0;vt=n+maxw*7+1;
for(int i=1;i<=n;i++){
add(vs,i,week[i-1].d);
}
for(int i=0;i<n;i++){
for(int k=0;k<week[i].w;k++){
for(int j=0;j<7;j++){
if(week[i].f[j]){
add(i+1,j+1+n+k*7,1);
}
}
}
}
for(int i=n+1;i<=n+maxw*7;i++){
add(i,vt,1);
}
int ans=dinic(vs,vt);
if(D==ans){
printf("Yes\n");
}
else{
printf("No\n");
}
}
return 0;
}