显示代码纯文本
#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;
const int N=1e5+10;
struct edge{int f,t,g;}w[N];
int n,m,k,p,S,T,head[N],next[N],cnt=1;
void add(int f,int t,int g){
w[++cnt]=(edge){f,t,g};
next[cnt]=head[f];
head[f]=cnt;
w[++cnt]=(edge){t,f,0};
next[cnt]=head[t];
head[t]=cnt;
}
struct st{
int x,i,df;
st(int X=0,int DF=0){x=X;i=head[x];df=DF;}
}z[N];
int l[N],top,ans;
#define V z[top].x
#define E z[top].i
#define F z[top].df
void change(){
int df=F;ans+=df;
for (int i=top-1;i;i--){
w[z[i].i].g-=df;
w[z[i].i^1].g+=df;
z[i].df-=df;
if (!z[i].df) top=i;
}
}
queue<int> Q;
void bfs(){
for (int i=0;i<=p;i++) l[i]=0;
l[S]=1;Q.push(S);
while (!Q.empty()){
int v=Q.front();Q.pop();
for (int i=head[v];i;i=next[i])
if (w[i].g&&!l[w[i].t])
l[w[i].t]=l[v]+1,Q.push(w[i].t);
}
}
bool dinic(){
bfs();
if (!l[T]) return 0;
z[top=1]=st(S,1e9);
while (top){
if (V==T){change();top--;E=next[E];}else
if (!E){l[V]=0;top--;E=next[E];}else
if (w[E].g&&l[w[E].t]==l[V]+1)
z[top+1]=st(w[E].t,min(F,w[E].g)),top++;
else E=next[E];
}
return 1;
}
int H[N],r[N],go[1010][1010],id[1010][1010];
void init(int T){
while (cnt>1) next[cnt--]=0;
ans=0;p=2;
for (int i=0;i<=T;i++){
id[0][i]=0;id[1][i]=1;id[2][i]=2;
for (int j=1;j<=n;j++) id[j+2][i]=++p;
}
for (int i=0;i<=p;i++) head[i]=0;
for (int i=1;i<=m;i++)
for (int j=1;j<=T;j++)
add(id[go[i][j-1]][j-1],id[go[i][j]][j],H[i]);
for (int i=1;i<=n;i++)
for (int j=1;j<=T;j++)
add(id[i+2][j-1],id[i+2][j],1e9);
add(1,2,k);
}
void solve(int l,int r){
if (l==r) return void(printf("%d\n",l==1000?0:l));
int mid=(l+r)>>1;
init(mid);
while (dinic());
if (ans!=k) solve(mid+1,r);else solve(l,mid);
}
int main()
{
freopen("home.in","r",stdin);
freopen("home.out","w",stdout);
scanf("%d%d%d",&n,&m,&k);
S=0;T=2;
for (int i=1;i<=m;i++){
scanf("%d%d",&H[i],&r[i]);
for (int j=0;j<r[i];j++){
scanf("%d",&go[i][j]);
if (go[i][j]) go[i][j]+=2;
}
for (int j=r[i];j<1010;j++) go[i][j]=go[i][j-r[i]];
}
solve(1,1000);
return 0;
}