题目链接: poj 1689
题目大意: 有个人想拍n部电影,每部电影限定每周哪几天可以拍
并且必须在第ki周之前把这部电影拍完,问能否拍完n部电影
解题思路: 把每部电影当作一个顶点,源点指向这些顶点,容量为该电影需要拍多少天
然后把每一天都当作顶点,某个工作可以在这天完成就连容量为1大边
每天的顶点指向汇点,容量也为1
最后求出最大流,满流则说明可以完成这些工作
PS:用邻接表时要注意反向边也要加入,因为需要不断增广直到最优解
代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 402
#define INF 0x3f3f3f3f
int n,m,S,E,Index,visit[MAX],flag[MAX][MAX],Map[MAX][MAX],listb[MAX];
struct snode{
int to,c,next;
}Edge[MAX*MAX];
struct node{
int c;
}edge[MAX][MAX];
int a[60][10],pre[MAX];
int Min(int a,int b)
{
return (a<b)?a:b;
}
void Add_edge(int a,int b,int c)
{
Edge[Index].c=c,Edge[Index].to=b;
Edge[Index].next=pre[a];
pre[a]=Index++;
}
bool BFS()
{
int i,s,e,v;
s=e=0;
memset(visit,0,sizeof(visit));
memset(flag,0,sizeof(flag));
visit[S]=1;
listb[s++]=S;
while(s!=e)
{
v=listb[e++];
if(v==E)
return true;
for(int i1=pre[v];i1!=-1;i1=Edge[i1].next)
{
i=Edge[i1].to;
if(Map[v][i]&&!visit[i])
{
flag[v][i]=1;
visit[i]=1;
listb[s++]=i;
}
}
}
return false;
}
int DFS(int v,int sum)
{
int s,t,i,to;
s=sum;
if(v==E||sum==0)
return sum;
for(i=pre[v];i!=-1;i=Edge[i].next)
{
to=Edge[i].to;
if(flag[v][to])
{
t=DFS(to,Min(sum,Map[v][to]));
Map[v][to]-=t;
Map[to][v]+=t;
sum-=t;
}
}
return s-sum;
}
void Solve()
{
while(BFS())
DFS(S,INF);
}
int main()
{
int i,j,Max,t;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
S=Max=Index=0;
memset(edge,0,sizeof(edge));
memset(pre,-1,sizeof(pre));
memset(Map,0,sizeof(Map));
for(i=1;i<=n;i++)
{
for(j=1;j<=9;j++)
{
scanf("%d",&a[i][j]);
}
if(a[i][9]>Max)
Max=a[i][9];
edge[S][i].c=a[i][8]; //前面
Map[S][i]=a[i][8]; //前面
}
E=n+(Max*7)+1;
for(i=1;i<=n;i++)
{
for(j=1;j<=a[i][9];j++)
{
for(int j1=1;j1<=7;j1++)
{
if(a[i][j1]==1)
{
edge[i][n+(j-1)*7+j1].c=1; //中间
Map[i][n+(j-1)*7+j1]=1; //中间
edge[n+(j-1)*7+j1][E].c=1; //后面
Map[n+(j-1)*7+j1][E]=1; //后面
}
}
}
}
for(i=S;i<=E;i++)
{
for(j=S;j<=E;j++)
{
if(edge[i][j].c)
{
Add_edge(i,j,edge[i][j].c);
Add_edge(j,i,-edge[i][j].c); //不存在,但是需要用到
}
}
}
Solve();
int pd=1;
for(i=1;i<=n;i++)
{
if(Map[S][i]!=0)
{
pd=0;
break;
}
}
if(pd)
printf("Yes\n");
else
printf("No\n");
}
return 0;
}