题目链接: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 }