Hdoj 3251 Being a Hero "to solve the minimum cut + output any set of minimum cut inside edge number"

Source: Internet
Author: User



Being a HeroTime limit:20000/10000 MS (java/others) Memory limit:32768/32768 K (java/others)
Total submission (s): 1252 Accepted Submission (s): 395
Special Judge


Problem Descriptionyou is the hero who saved your country. As promised, the king would give you some cities of the country, and you can choose which ones to own!

But don ' t get too excited. The cities should not being reachable from the capital – the king does not want to accidentally enter your area. In order to satisfy the condition, you have to destroy some roads. What's worse, you had to pay for that – each road was associated with a some positive cost. That's, your final income is the total value of the cities, and minus the total cost of destroyed roads.

Note that all road is a unidirectional, i.e only one direction is available. Some cities is reserved for the king, so you cannot take any of them even if they ' re unreachable from the capital. The capital city was always the city number 1.

Inputthe first line contains a single integer t (t <=), the number of test cases. Each case begins with three integers n, M, F (1 <= F < n <=, 1 <= m < 100000), the number of cities, n Umber of roads, and number of cities that's can take. Cities is numbered 1 to N. Each of the following m lines contains three integers u, V, W, denoting a road from city u to City v, with cost W. Each of the following F lines contains-integers u and W, denoting an available city U, with value W.
Outputfor each test case, print the case number and the best final income on the first line. In the second line, print E, the number of roads you should destroy, followed by e integers, the IDs of the destroyed road S. Roads is numbered 1 to m in the same order they appear in the input. If there is more than one solution, any one would do.
Sample Input
24 4 21 2 21 3 33 2 42 4 12 34 44 4 21 2 21 3 33 2 12 4 12 34 4

Sample Output
Case 1:31 4Case 2:42 1 3



Two, take a two-hour car. Exhausted. /(ㄒoㄒ)/~~


Test Instructions: There are n cities (numbered from 1 to N) and the M-bar connecting the city has an edge. You can choose the F city, but the City 1 cannot reach this F city, so you need to destroy some sides. Now give you the cost of destroying each side and the value of the F city, ask you for the maximum value you can get, and output the number of sides that need to be destroyed and the number of that side (if there are multiple scenarios, you can output any one).


Idea: Minimum cut, maximum value is the total value of F city-minimum cut. As for the output of the smallest cut inside the number, only in the residual network to find the City 1 can reach all points, these points must constitute a set of S. Finally, a forward arc that traverses the M bar has a forward edge, and if the starting point of the arc is in the s set and the end point is absent, then the arc is an edge in the smallest cut.


Build: Set Super source point sources, super sink point sink

1, there are to the edge of <u, v> built edge, edge for the cost of destroying the side;

2,source to the city 1 built side, capacity for infinity;

3, the selected F-City is built on the side of the sink, the capacity for the value of the city.

Source->sink run a maximum flow to find the smallest cut.


AC Code:

#include <cstdio> #include <cstring> #include <algorithm> #include <queue> #define MAXN 1010# Define MAXM 300000+10#define INF 0x3f3f3f3fusing namespace std;struct edge{int from, to, cap, flow, ID, next;//id record Edge Number};     Edge Edge[maxm];int HEAD[MAXN], Edgenum;int DIST[MAXN], Cur[maxn];bool vis[maxn];int N, M, f;int source, Sink;void Init () {    Edgenum = 0; Memset (Head,-1, sizeof (head));}    void Addedge (int u, int v, int w, int id) {Edge E1 = {u, V, W, 0, ID, head[u]};    Edge[edgenum] = E1;    Head[u] = edgenum++;    Edge E2 = {V, u, 0, 0, ID, head[v]};    Edge[edgenum] = E2; HEAD[V] = edgenum++;}   int val;//All can get the value of the City void Getmap () {Source = 0, sink = n+1;   int A, b, C;       for (int i = 1; I <= M; i++) {scanf ("%d%d%d", &a, &b, &c);   Addedge (A, B, C, I);//Note that there is a forward edge//addedge (b, A, c, i);   } val = 0;       The other sides of the M bar are the virtual sides. The default ID is 0 for (int i = 1; I <= F; i++) {scanf ("%d%d", &a, &c);       Val + = C; Addedge (A, Sink, C, 0);    } addedge (source, 1, INF, 0),//source to City 1,}bool BFS (int s, int t) {queue<int> Q;    memset (Dist,-1, sizeof (Dist));    Memset (Vis, false, sizeof (VIS));    Dist[s] = 0;    Vis[s] = true;    Q.push (s); while (!        Q.empty ()) {int u = q.front ();        Q.pop ();            for (int i = head[u]; i =-1; i = Edge[i].next) {Edge E = Edge[i];                if (!vis[e.to] && e.cap > E.flow) {dist[e.to] = Dist[u] + 1;                if (e.to = = t) return true;                Vis[e.to] = true;            Q.push (e.to); }}} return false;}    int DFS (int x, int a, int t) {if (x = = T | | a = = 0) return A;    int flow = 0, F;        for (int &i = cur[x]; i =-1; i = Edge[i].next) {Edge &e = Edge[i]; if (dist[e.to] = = Dist[x] + 1 && (f = DFS (e.to, Min (A, e.cap-e.flow), T)) > 0) {Edge[i].flo            W + = f;          Edge[i^1].flow-= f;  Flow + + F;            A-= f;        if (a = = 0) break; }} return flow;}    int Maxflow (int s, int t) {int flow = 0;        while (BFS (s, t)) {memcpy (cur, head, sizeof (head));    Flow + = DFS (s, INF, T); } return flow;}        void find_s (int u)//The S-set {for (int i = head[u]; i = edge[i].next) {Edge E = edge[i] in the residual network where the source point can be found;        if (vis[e.to]) continue;            if (E.cap > E.flow)//cannot be full stream {vis[e.to] = true;        find_s (e.to);    }}}int rec[100000+1];//record minimum cut inside edge number void output () {int ans = 0;//statistics to remove the number of sides memset (Vis, false, sizeof (VIS));             find_s (1);//To start from 1 for (int i = 0; i < edgenum; i+=2)//Traverse forward arc {if (edge[i].id = = 0)//an edge with ID 0 means that the M-bar solid side has traversed        Break  if (Vis[edge[i].from] &&!vis[edge[i].to])//beginning at the end of S set is not rec[ans++] = edge[i].id;//record} printf ("%d",    ANS);    for (int i = 0; i < ans; i++) printf ("%d", rec[i]); printf ("\ n");} int main () {inT T, k = 1;    scanf ("%d", &t);        while (t--) {scanf ("%d%d%d", &n, &m, &f);        Init ();        Getmap ();        printf ("Case%d:%d\n", k++, Val-maxflow (source, sink));    Output (); } return 0;}


Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

Hdoj 3251 Being a Hero "to solve the minimum cut + output any set of minimum cut inside edge number"

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.