POJ_2125
Because the final goal is that there is no x-> y edge, we can construct a network stream model (where x-> y connects to an edge with a capacity of INF ), if a path such as S-> x-> y-> T exists, this edge still exists, you need to delete the inbound or outbound edge of a vertex to delete this edge. At this time, we will find that if any vertex I is represented by only one vertex, there is no way to distinguish between the deleted edge and the outbound edge. Therefore, we need to split I into two vertices I and I ', then the side x-> y above is changed to x-> y '. In this case, we can make it clear that the path S-> x-> y'-> T no longer has the cost. There are no more than two measures, you can either disconnect S-> x, which means that the edge does not have a starting point, so the cost is the cost of the exit of point x, that is, Wx -, or you have to disconnect y'-> T, which is equivalent to the end point of the edge, so the cost is the cost of disconnecting the inbound edge of point y, that is, Wy +. After creating an image, the minimum cost is the minimum cost for the original image.
Next, we will consider how to solve the problem of the input solution. In fact, after the minimum cut, the points on the source image can be divided into two parts, one part is the points that can arrive from S (recorded as the points of S set ), the other part is the point that can be reached to T (recorded as the point of T set), and the point of S set indicates that the vertex is not deleted from the edge, the vertices in the T set do not delete the inbound edges for these vertices. Of course, some vertices are deleted as well as the inbound edges, but it doesn't matter. Just put all these points into the T set, because it can be equivalent to some sides not being deleted, so it won't affect the final result.
Next, we need to find the points in the S set. We only need to follow the above definition to start from the edge of the non-full stream, and the points passed through are all points in the S set, in this way, we divide points into the S set part and the T set part. Because we have obtained the minimum cut, if the vertex in the T set is connected to the Source Vertex, then obviously this edge should be cut edge. In the same sense, if the vertex in the S set is connected to the sink vertex, then these edges should also be cut, so that we can find all the cut edges.
#include<stdio.h>#include<string.h>#include<algorithm>#define MAXD 210#define MAXM 10410#define INF 0x3f3f3f3fint N, M, first[MAXD], e, next[MAXM], v[MAXM], flow[MAXM];int S, T, d[MAXD], q[MAXD], work[MAXD], vis[MAXD];struct List{ int x; char ch;}list[MAXD];void add(int x, int y, int z){ v[e] = y, flow[e] = z; next[e] = first[x], first[x] = e ++;}void init(){ int i, x, y; S = 0, T = N * 2 + 1; memset(first, -1, sizeof(first[0]) * (T + 1)), e = 0; for(i = 1; i <= N; i ++) { scanf("%d", &x); add(N + i, T, x), add(T, N + i, 0); } for(i = 1; i <= N; i ++) { scanf("%d", &x); add(S, i, x), add(i, S, 0); } for(i = 0; i < M; i ++) { scanf("%d%d", &x, &y); add(x, N + y, INF), add(N + y, x, 0); }}int bfs(){ int i, j, rear = 0; memset(d, -1, sizeof(d[0]) * (T + 1)); d[S] = 0, q[rear ++] = S; for(i = 0; i < rear; i ++) for(j = first[q[i]]; j != -1; j = next[j]) if(flow[j] && d[v[j]] == -1) { d[v[j]] = d[q[i]] + 1, q[rear ++] = v[j]; if(v[j] == T) return 1; } return 0;}int dfs(int cur, int a){ if(cur == T) return a; for(int &i = work[cur]; i != -1; i = next[i]) if(flow[i] && d[v[i]] == d[cur] + 1) if(int t = dfs(v[i], std::min(a, flow[i]))) { flow[i] -= t, flow[i ^ 1] += t; return t; } return 0;}int dinic(){ int ans = 0, t; while(bfs()) { memcpy(work, first, sizeof(first[0]) * (T + 1)); while(t = dfs(S, INF)) ans += t; } return ans;}void DFS(int cur){ int i; d[cur] = 1; for(i = first[cur]; i != -1; i = next[i]) if(flow[i] != 0 &&!d[v[i]]) DFS(v[i]);}void solve(){ int i, ans = 0; printf("%d\n", dinic()); memset(d, 0, sizeof(d[0]) * (T + 1)); DFS(S); memset(vis, 0, sizeof(vis[0]) * (T + 1)); for(i = first[S]; i != -1; i = next[i]) if(!d[v[i]] && !vis[v[i]]) vis[v[i]] = 1, list[ans].ch = '-', list[ans].x = v[i], ++ ans; for(i = first[T]; i != -1; i = next[i]) if(d[v[i]] && !vis[v[i]]) vis[v[i]] = 1, list[ans].ch = '+', list[ans].x = v[i] - N, ++ ans; printf("%d\n", ans); for(i = 0; i < ans; i ++) printf("%d %c\n", list[i].x, list[i].ch);}int main(){ while(scanf("%d%d", &N, &M) == 2) { init(); solve(); } return 0;}