Topic: To a network, ask if there is a stream just C. If it does not exist, is there an arc, so that the capacity of the arc can be changed to just C flow?
Problem Analysis: First find the maximum flow, if the maximum flow is not smaller than C, then there must be a flow just C. Otherwise, find the minimum cut set and then enumerate each arc to change its capacity to see if there is a stream that is just c.
The code is as follows:
# include<iostream># include<cstdio># include<cmath># include<string># include<vector ># include<list># include<set># include<map># include<queue># include<cstring># Include<algorithm>using namespace std;# define LL long long# define REP (i,s,n) for (int i=s;i<n;++i) # define CL (A, b) memset (A,b,sizeof (a)) # define CLL (A,b,n) Fill (a,a+n,b) const double inf=1e30;const int Inf=1<<30;const int maxn= 10005;struct edge{int fr,to; LL CAP,FW; Edge (int _fr,int _to,ll _cap,ll _fw): fr (_fr), to (_to), Cap (_CAP), FW (_FW) {} BOOL operator < (const Edge &a) const{ if (fr==a.fr) return to<a.to; Return fr<a.fr; }};vector<edge>edges,tedges,ans;vector<int>g[2*maxn];vector<int>mincut;int N,E,cur[105],vis[ 105],D[105]; LL c,flow;int s,t;void init () {flow=0; S=1,t=n; Edges.clear (); REP (i,0,n+1) g[i].clear ();} void Addedge (int u,int v,ll c) {Edges.push_back (Edge (u,v,c,0));Edges.push_back (Edge (v,u,0,0)); int m=edges.size (); G[u].push_back (m-2); G[v].push_back (m-1);} BOOL BFS () {CL (vis,0); queue<int>q; Vis[s]=1; d[s]=0; Q.push (s); while (!q.empty ()) {int X=q.front (); Q.pop (); REP (I,0,g[x].size ()) {Edge &e=edges[G[x][i]]; if (!VIS[E.TO]&&E.CAP>E.FW) {vis[e.to]=1; d[e.to]=d[x]+1; Q.push (e.to); }}} return vis[t];} LL DFS (int x,ll a) {if (x==t| | a==0) return A; LL flow=0,f; for (int &i=cur[x];i<g[x].size (); ++i) {Edge &e=edges[G[x][i]]; if (d[x]+1==d[e.to]&& (F=dfs (E.to,min (A,E.CAP-E.FW))) >0) {e.fw+=f; Edges[g[x][i]^1].fw-=f; Flow+=f; A-=f; if (a==0) break; }} return flow;} BOOL Dinic () {while (BFS ()) {CL (cur,0); Flow+=dfs (S,inf); if (flow>=c) return true; } return false;} voidFindcut () {mincut.clear (); for (int i=0;i<edges.size (); i+=2) {Edge &e=edges[i]; if (vis[e.fr]&&!vis[e.to]) mincut.push_back (i); }}void Tofind () {findcut (); Ans.clear (); Tedges.clear (); int len=edges.size (); REP (I,0,len) tedges.push_back (Edges[i]); LL F=flow; REP (I,0,mincut.size ()) {edges[mincut[i]].cap+=c; if (Dinic ()) Ans.push_back (Edges[mincut[i]); Flow=f; Edges.clear (); REP (J,0,len) edges.push_back (Tedges[j]); }}void solve (int CAs) {printf ("Case%d:", CAs); if (c==0| | Dinic ()) {printf ("possible\n"); }else{Tofind (); int len=ans.size (); if (len>0) {printf ("possible option:"); Sort (Ans.begin (), Ans.end ()); REP (I,0,len) printf ("(%d,%d)%c", Ans[i].fr,ans[i].to, (i==len-1)? ' \ n ': ', '); }else printf ("Not possible\n"); }}void read () {int A, B; LL C; while (e--) {scanf ("%d%d%lld", &a,&b,&C); Addedge (A,B,C); }}int Main () {int cas=0; while (scanf ("%d%d%lld", &n,&e,&c), n| e| C) {init (); Read (); Solve (++cas); } return 0;}
UVA-11248 Frequency Hopping (max Flow + min cut)