题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3157
You’ve just built a circuit board for your new robot, and now you need to power it. Your robot circuit consists of a number of electrical components that each require a certain amount of current to operate. Every component has a + and a - lead, which are connected on the circuit board at junctions. Current flows through the component from + to - (but note that a component does not "use up" the current: everything that comes in through the + end goes out the - end).
The junctions on the board are labeled 1, ..., N, except for 
two special junctions labeled + and - where the power supply terminals are 
connected. The + terminal only connects + leads, and the - terminal only 
connects - leads. All current that enters a junction from the - leads of 
connected components exits through connected + leads, but you are able to 
control how much current flows to each connected + lead at every junction 
(though methods for doing so are beyond the scope of this problem1). 
Moreover, you know you have assembled the circuit in such a way that there are 
no feedback loops (components chained in a manner that allows current to flow in 
a loop).
In the interest of saving power, and also to ensure that your circuit does not overheat, you would like to use as little current as possible to get your robot to work. What is the smallest amount of current that you need to put through the + terminal (which you can imagine all necessarily leaving through the - terminal) so that every component on your robot receives its required supply of current to function?
  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<cstdlib>
  5 #include<cmath>
  6 #include<algorithm>
  7 #include<queue>
  8 #define inf 0x7fffffff
  9 using namespace std;
 10 const int maxn=600;
 11 const int M = 100000+10;
 12 
 13 struct Edge
 14 {
 15     int to,cap,next;
 16 }edge[M*2];
 17 int head[maxn],edgenum;
 18 int n,m,from,to,vnum,s,t;
 19 
 20 void add(int u,int v,int cap)
 21 {
 22     edge[edgenum].to=v;
 23     edge[edgenum].cap=cap;
 24     edge[edgenum].next=head[u];
 25     head[u]=edgenum++;
 26 
 27     edge[edgenum].to=u;
 28     edge[edgenum].cap=0;
 29     edge[edgenum].next=head[v];
 30     head[v]=edgenum++;
 31 }
 32 
 33 int level[maxn];
 34 int gap[maxn];
 35 void bfs(int to)
 36 {
 37     memset(level,-1,sizeof(level));
 38     memset(gap,0,sizeof(gap));
 39     level[to]=0;
 40     gap[level[to] ]++;
 41     queue<int> Q;
 42     Q.push(to);
 43     while (!Q.empty())
 44     {
 45         int u=Q.front() ;Q.pop() ;
 46         for (int i=head[u] ;i!=-1 ;i=edge[i].next)
 47         {
 48             int v=edge[i].to;
 49             if (level[v] != -1) continue;
 50             level[v]=level[u]+1;
 51             gap[level[v] ]++;
 52             Q.push(v);
 53         }
 54     }
 55 }
 56 
 57 int cur[maxn];
 58 int pre[maxn];
 59 int SAP(int from,int to)
 60 {
 61     bfs(to);
 62     memset(pre,-1,sizeof(pre));
 63     memcpy(cur,head,sizeof(head));
 64     int u=pre[from]=from,flow=0,aug=inf;
 65     gap[from]=vnum;
 66     while (level[from]<vnum)
 67     {
 68         bool flag=false;
 69         for (int &i=cur[u] ;i!=-1 ;i=edge[i].next)
 70         {
 71             int v=edge[i].to;
 72             if (edge[i].cap && level[u]==level[v]+1)
 73             {
 74                 flag=true;
 75                 aug=min(aug,edge[i].cap);
 76                 pre[v]=u;
 77                 u=v;
 78                 if (v==to)
 79                 {
 80                     flow += aug;
 81                     for (u=pre[u] ;v!=from ;v=u ,u=pre[u])
 82                     {
 83                         edge[cur[u] ].cap -= aug;
 84                         edge[cur[u]^1 ].cap += aug;
 85                     }
 86                     aug=inf;
 87                 }
 88                 break;
 89             }
 90         }
 91         if (flag) continue;
 92         int minlevel=vnum;
 93         for (int i=head[u] ;i!=-1 ;i=edge[i].next)
 94         {
 95             int v=edge[i].to;
 96             if (edge[i].cap && level[v]<minlevel)
 97             {
 98                 minlevel=level[v];
 99                 cur[u]=i;
100             }
101         }
102         if (--gap[level[u] ]==0) break;
103         level[u]=minlevel+1;
104         gap[level[u] ]++;
105         u=pre[u];
106     }
107     return flow;
108 }
109 
110 int main()
111 {
112     while (scanf("%d%d",&n,&m)!=EOF)
113     {
114         if (!n && !m) break;
115         memset(head,-1,sizeof(head));
116         edgenum=0;
117         char c[5],c2[5];
118         int u,v;
119         int cap,f=M;
120         s=0 ;t=n+1 ;from=t+1 ;to=from+1 ;
121         vnum=to+1;
122         int sum=0;
123         for (int i=0 ;i<m ;i++)
124         {
125             scanf("%s%s%d",&c,&c2,&cap);
126             sum += cap;
127             if (c[0]==‘+‘) u=s;
128             else sscanf(c,"%d",&u);
129             if (c2[0]==‘-‘) v=t;
130             else sscanf(c2,"%d",&v);
131             add(u,v,f-cap);
132             add(from,v,cap);
133             add(u,to,cap);
134             //cout<<"debug"<<endl;
135         }
136         int Maxflow=SAP(from,to);
137         int d=edgenum;
138         add(t,s,inf);
139         Maxflow += SAP(from,to);
140         int flag=0;
141         for (int i=head[from] ;i!=-1 ;i=edge[i].next)
142         {
143             if (edge[i].cap) {flag=1;break; }
144         }
145         if (Maxflow==sum) printf("%d\n",edge[(d^1)].cap);
146         else printf("impossible\n");
147     }
148     return 0;
149 }
原文:http://www.cnblogs.com/huangxf/p/4270805.html