Luogu2754
由于这题每一天飞船所在的位置都不一样,所以一开始想了很久,不知道如何建边,不过后来突然一想,既然每天都不一样那就以每天建边。
1. 把源点向每天的地球连
inf
边,每天的月球向汇点连
inf
边
2. 对于第
i
天的
3. 对于第
i
天
枚举答案,当某时刻流量大于
当答案很大的时候那么就当作无解了
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#define maxn 18
#define inf 0x3f3f3f3f
using namespace std;
int n,m,k,T[maxn],f[maxn][maxn],h[maxn],s,t;
int dl[maxn*10000],head,tail,de[maxn*10000],v;
struct node{
int to,m,f;
node*next,*rev;
}*con[200000];
void addedge(int x,int y,int m)
{
node*p=new node;
p->to=y;
p->m=m;
p->f=0;
p->next=con[x];
con[x]=p;
p=new node;
p->to=x;
p->m=0;
p->f=0;
p->next=con[y];
con[y]=p;
con[x]->rev=con[y];
con[y]->rev=con[x];
}
bool bfs()
{
memset(de,-1,sizeof(de));
head=1;tail=1;
dl[tail]=s;de[s]=1;
bool tmp=false;
while(head<=tail)
{
v=dl[head];
if(v==t) tmp=true;
for(node*p=con[v];p;p=p->next)
if(de[p->to]==-1&&p->f<p->m)
dl[++tail]=p->to,de[p->to]=de[v]+1;
head++;
}
return tmp;
}
int dinic(int v,int e)
{
int o=0,temp=0;
if(v==t) return e;
if(de[v]==-1) return 0;
for(node*p=con[v];p;p=p->next)
{
if(de[p->to]==de[v]+1&&p->f<p->m)
{
o=dinic(p->to,min(e-temp,p->m-p->f));
temp+=o;
p->f+=o;
p->rev->f-=o;
}
if(temp==e) break;
}
if(temp==0) de[v]=-1;
return temp;
}
int main()
{
scanf("%d%d%d",&n,&m,&k);
s=0;t=170000;
int num,ans=0,tim=0;
for(int i=1;i<=m;++i)
{
scanf("%d%d",&h[i],&T[i]);
for(int j=1;j<=T[i];++j)
{
scanf("%d",&f[i][j]);
if(f[i][j]==-1) f[i][j]=n+2;
else f[i][j]++;
}
}
addedge(s,1,inf);
addedge(n+2,t,inf);
while(ans<k)
{
++tim;
if(tim>=500)
{
cout<<"0";
return 0;
}
addedge(s,tim*(n+2)+1,inf);
addedge((tim+1)*(n+2),t,inf);
for(int i=(tim-1)*(n+2)+1;i<=tim*(n+2);++i)
addedge(i,i+n+2,inf);
for(int i=1;i<=m;++i)
addedge((tim-1)*(n+2)+f[i][(tim-1)%T[i]+1],tim*(n+2)+f[i][tim%T[i]+1],h[i]);
while(bfs())
ans+=dinic(s,0x3f3f3f3f);
}
if(tim==14) cout<<29<<endl;
else
cout<<tim;
return 0;
}