解析
容易想到对每个时间的空间站都建一个点。
然后发现循环问题很难搞。
然后我就一直想从 lcm 下文章,结果 lcm 可以到3e5,于是就寄了…
qwq
注意到本题的数据范围极小!
那个3e5云云是不可能跑出来的,事实上,答案不可能超过 nknknk。(最差也就是每次都只有一个人乘一班环游世界车摆烂)
所以,我们可以更加暴力的做。
枚举当前时间。
然后就好办了,每次把当前时间下的空间站和星球建出来,暴力连边即可。
设答案为 www,那么点数为 O(wn)O(wn)O(wn),边数为 O(wm)O(wm)O(wm)。
跑的飞快。
代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define debug(...) fprintf(stderr,__VA_ARGS__)
#define ok debug("OK\n")
inline ll read(){ll x(0),f(1);char c=getchar();while(!isdigit(c)){if(c=='-') f=-1;c=getchar();}while(isdigit(c)){x=(x<<1)+(x<<3)+c-'0';c=getchar();}return x*f;
}
const int N=2e5+100;
const int M=1e6+100;
const int inf=1e9;int n,m;int s,t,tot;
struct node{int to,nxt,cap;
}p[N<<1];
int fi[N],cur[N],cnt;
inline void addline(int x,int y,int c){p[++cnt]=(node){y,fi[x],c};fi[x]=cnt;
}
inline void add(int x,int y,int c){addline(x,y,c);addline(y,x,0);return;
}
int bel[N],q[N],st,ed;
int bfs(){fill(bel,bel+1+tot,0);q[st=ed=1]=s;bel[s]=1;while(st<=ed){int now=q[st++];for(int i=cur[now]=fi[now];~i;i=p[i].nxt){ int to=p[i].to;if(!p[i].cap||bel[to]) continue;bel[to]=bel[now]+1;q[++ed]=to;}}return bel[t];
}
int dfs(int x,int lim){if(x==t||lim==0) return lim;int res(0);for(int &i=cur[x];~i;i=p[i].nxt){int to=p[i].to;if(bel[to]!=bel[x]+1) continue;int add=dfs(to,min(lim,p[i].cap));res+=add;lim-=add;p[i].cap-=add;p[i^1].cap+=add;if(!lim) break;}if(!res) bel[x]=-1;return res;
}
ll flow;
void dinic(){ll tmp=0;while(bfs()){while((tmp=dfs(s,2e9))) flow+=tmp;}return;
}int id[16][1050],k;
int num[25],x[25][16],h[25];
void build(int tim){for(int i=1;i<=n;i++){id[i][tim]=++tot;if(tim) add(id[i][tim-1],id[i][tim],inf);}add(s,id[2][tim],inf);add(id[1][tim],t,inf);if(tim){for(int i=1;i<=m;i++){int pl=(tim-1)%num[i]+1;//printf("add: (%d %d)->(%d %d) cap=%d\n",//x[i][pl],tim-1,x[i][pl%num[i]+1],tim,h[i]);add(id[x[i][pl]][tim-1],id[x[i][pl%num[i]+1]][tim],h[i]);}}return;
}
signed main(){#ifndef ONLINE_JUDGE//freopen("a.in","r",stdin);//freopen("a.out","w",stdout);#endifmemset(fi,-1,sizeof(fi));cnt=-1;n=read()+2;m=read();k=read();s=++tot;t=++tot;for(int i=1;i<=m;i++){h[i]=read();num[i]=read();for(int j=1;j<=num[i];j++) x[i][j]=read()+2;}build(0);for(int tim=1;tim<1000;tim++){build(tim);dinic();if(flow>=k){printf("%d\n",tim);return 0;}}//printf("%d\n",flow);printf("0");return 0;
}
/*
0 1 1
1 2 0 -1
*/