Destroying the Graph
Time Limit: 2000MS |
|
Memory Limit: 65536K |
Total Submissions: 7570 |
|
Accepted: 2423 |
|
Special Judge |
Description
Alice and Bob play the following game. First, Alice draws some directed graph with N vertices and M arcs. After the Bob tries to destroy it. In a move he could take any vertex of the graph and remove either all arcs incoming to this vertex, or all arcs outgoing F Rom this vertex.
Alice assigns the costs to each vertex:wi+ and wi-. If Bob removes all arcs incoming into the i-th vertex he pays wi+ dollars to Alice, and if he removes outgoing arcs he pay S wi-dollars.
Find out how minimal sum Bob needs to remove all arcs from the graph.
Input
Input file describes the graph Alice has drawn. The first line of the input file contains N and M (1 <= n <=, 1 <= M <= 5000). The second line contains N integer numbers specifying wi+. The third line defines wi-in a similar. All costs is positive and does not exceed 106. Each of the following M lines contains and integers describing the corresponding arc of the graph. Graph may contain loops and parallel arcs.
Output
On the first line of the output file print W---the minimal sum Bob must has to remove all arcs from the graph. On the second line print K---the number of moves Bob needs to do it. After the print K lines that describe Bob ' s moves. Each line must first contain the number of the vertex and so ' + ' or '-' character, separated by one space. Character ' + ' means that Bob removes all arcs incoming to the specified vertex and '-' That's Bob removes all arcs Outgoin G from the specified vertex.
Sample Input
3 61 2 34 2 11 21 13 21 23 12 3
Sample Output
531 +2-2 +
Test instructions: gives n points, n edges. There are two kinds of operations. One is to select a point to remove all the edges of the point. The other is to choose a point to remove all the edges of the point. The
gives you the cost of selecting two actions for each point. The minimum cost required to delete all edges.
Idea: Set the delete edge for action A, delete the out edge for action B. For each edge (U,V), you must select at least a (v) or B (U) to operate in order to delete this edge.
This conforms to the model of the point overlay set. For each point, the
can be split into two points, one for operation A (n+1,2*n) and the other for Action B (1,n). The
therefore increases the source point s (0) and the meeting point T (2*n+1). For action B that corresponds to the delete out edge. From S to each point an edge is attached, the capacity is the corresponding cost.
for the Delete-in-edge operation A, each point to the T is connected to an edge, and the capacity is the corresponding cost. The
is then given a point edge (i, j), a connection point (I,j+n), and a capacity of INF. The
then asks for the minimum cut, which is the minimum cost.
for cutting edges. Point S can be reached in the last BFS operation.
So for the (1~n) point. If the point S cannot reach this point, then the corresponding point edge is cut edge. The point is to delete the edge operation. The
for (n+1~2*n) the point. If the point S can reach this point, then the corresponding point is cut edge. The point is to delete the in-side operation.
#include <iostream> #include <cstring> #include <cstdio> #include <string> #include <vector > #include <queue>using namespace Std;int N, M; #define MAXN 110const int inf = 0x3f3f3f3f;struct edge{int from, to , cap, flow; Edge (int f, int t, int c, int fl) {from = f; to = t; cap = c; flow = FL;}}; Vector <Edge> edges;vector <int> g[maxn*2];int vis[maxn*2], d[maxn*2], Cur[maxn*2];int N, M, s, t;void Addedge (int from, int. to, int cap) {Edges.push_back (Edge (from, to, Cap, 0)), Edges.push_back (The Edge (to, from, 0, 0)); m = Edges.size (); G[from].push_back (m-2); G[to].push_back (m-1);} BOOL BFs () {memset (Vis, 0, sizeof (VIS)), vis[s] = 1;d[s] = 0;queue <int> Q;q.push (s), while (!q.empty ()) {int u = Q.front (); Q.pop (); for (int i = 0; i < g[u].size (); i++) {Edge &e = edges[g[u][i]];if (!vis[e.to] && e.cap > E.flow) {V Is[e.to] = 1;d[e.to] = D[u]+1;q.push (e.to);}}} return vis[t];} int dfs (int x, int a) {if (x = = T | | a = = 0) return A;int flow = 0, f;for (int &AMp;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.flow))) > 0) {e.flow + = F;edges[g[x][i]^1].flow-= F;flow + F;a-= f;if (A = = 0) break;}} return flow;} int Maxflow () {int flow = 0;while (BFS ()) {memset (cur, 0, sizeof (cur)); flow + = DFS (s, INF);} return flow;} int WIN[MAXN], wout[maxn];int main () {~scanf ("%d%d", &n, &m)) {edges.clear (); for (int i = 0; i < maxn*2; i++ ) g[i].clear (); for (int i = 1; I <= n; i++) scanf ("%d", &win[i]), for (int i = 1; I <= N; i++) scanf ("%d", &wou T[i]); s = 0; t = 2*n+1; n = n;for (int i = 1; I <= N; i++) {Addedge (S, I, wout[i]); Addedge (I+n, T, Win[i]);} for (int i = 1; I <= M; i++) {int A, b;scanf ("%d%d", &a, &b); Addedge (A, b+n, INF);} int ans = maxflow ();p rintf ("%d\n", ans); int cnt = 0;for (int i = 1; I <= 2*n; i++) {if (Vis[i] && i > N) cnt++; if (!vis[i] && i <= N) cnt++;} printf ("%d\n", CNT); for (int i = 1; I <= 2*n; i++) {iF (vis[i] && i > N) printf ("%d +\n", i-n), if (!vis[i] && i <= N) printf ("%d-\n", i);}} return 0;}
POJ 2125 destroying the Graph minimum point weight cover set + split + seek cutting edge