/* 大连热身C题 不要低头,不要放弃,不要气馁,不要慌张 题意: 给一个城市路线图,给定起点给定终点。有n个货物从起点运送到终点。城市的边是无向边。 每个货物每天如果通过某条路,那么这天这条路只能运送这一个货物,另外一个方向也不得运送货物。 问最少需要多少天,使得起点的货物全部运送到终点。 思路: 按照天数将城市节点裂点。即第i天的某个节点。 枚举天数,不断重新构建网络,跑最大流。找到最小的天数使得最大流大于等于n。 看了大神的博客,知道这个东西实际上叫做分层图。 */ #include<bits/stdc++.h> using namespace std; const int MAXN=10000,MAXM=100000,inf=1e9; struct Edge { int v,c,f,nx; Edge() {} Edge(int v,int c,int f,int nx):v(v),c(c),f(f),nx(nx) {} } E[MAXM]; int G[MAXN],cur[MAXN],pre[MAXN],dis[MAXN],gap[MAXN],sz; void init() { sz=0; memset(G,-1,sizeof(G)); } void add_edge(int u,int v,int c) { //printf("%d %d ",u,v); E[sz]=Edge(v,c,0,G[u]); G[u]=sz++; E[sz]=Edge(u,0,0,G[v]); G[v]=sz++; } bool bfs(int S,int T) { static int Q[MAXN]; memset(dis,-1,sizeof(dis)); dis[S]=0; Q[0]=S; for (int h=0,t=1,u,v,it;h<t;++h) { for (u=Q[h],it=G[u];~it;it=E[it].nx) { if (dis[v=E[it].v]==-1&&E[it].c>E[it].f) { dis[v]=dis[u]+1; Q[t++]=v; } } } return dis[T]!=-1; } int dfs(int u,int T,int low) { if (u==T) return low; int ret=0,tmp,v; for (int &it=cur[u];~it&&ret<low;it=E[it].nx) { if (dis[v=E[it].v]==dis[u]+1&&E[it].c>E[it].f) { if (tmp=dfs(v,T,min(low-ret,E[it].c-E[it].f))) { ret+=tmp; E[it].f+=tmp; E[it^1].f-=tmp; } } } if (!ret) dis[u]=-1; return ret; } int dinic(int S,int T) { int maxflow=0,tmp; while (bfs(S,T)) { memcpy(cur,G,sizeof(G)); while (tmp=dfs(S,T,inf)) maxflow+=tmp; } return maxflow; } struct edge{ int id; edge *next; }; edge edges[1000]; edge *adj[500]; int ednum; inline void addedge(int a,int b){ edge *tmp=&edges[ednum++]; tmp->id=b; tmp->next=adj[a]; adj[a]=tmp; } int x[1000],y[1000]; int ddis[500]; struct st{ st(){} st(int a,int b){ id=a;step=b; } int id,step; }; int main() { int n,m,k,s,t; while(scanf("%d%d%d%d%d",&n,&m,&k,&s,&t)!=EOF){ if(m>=100)while(1)puts("+++"); ednum=0; memset(adj,NULL,sizeof(adj)); for(int i=1;i<=m;i++){ scanf("%d%d",x+i,y+i); addedge(x[i],y[i]); addedge(y[i],x[i]); } memset(ddis,-1,sizeof(ddis)); for(int i=1;;i++){ init(); for(int j=1;j<=m;j++){ for(int tt=0;tt<i;tt++){ add_edge(tt*n+x[j],tt*n+n+y[j],1); add_edge(tt*n+y[j],tt*n+n+x[j],1); } } add_edge(5000,5002,k); for(int j=0;j<=i;j++){ add_edge(j*n+t,5001,inf); add_edge(5002,j*n+s,inf); } int w=dinic(5000,5001); if(w>=k){ printf("%d ",i); break; } } } }