自己的构图和搜的题解不太一样,果然构图都不太一样(想法比较奇葩。。。。,建议另寻题解,但是有个提醒,图论看了构图也就没有含义了,因为敲代码就是那几分钟的事情,构图却要想很久)
把一星期拆成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;
}