HDOJ 3488 Tour "minimum cost Max Flow" "km algorithm"

Source: Internet
Author: User


TourTime limit:3000/1000 MS (java/others) Memory limit:65535/65535 K (java/others)
Total submission (s): 2299 Accepted Submission (s): 1151


Problem DescriptionIn The Kingdom of Henryy, there is n (2 <= N <=) cities, with M (M <= 30000) one-way road s connecting them. You is lucky enough to has a chance to has a tour in the kingdom. The route should is designed as:the route should contain one or more loops. (a loop is a route like:a->b->......->p->a.)
Every city should is just in one route.
A Loop should has at least and cities. In one route, each city should is visited just once. (The only exception is, the first and the last city should are the same and this are visited twice.)
The total distance the N roads you has chosen should be minimized.

Inputan integer T in the first line indicates the number of the the test cases.
In each test case, the first line contains integers N and M, indicating the number of the cities and the one-way roads . Then M lines followed, each of the line have three integers U, V and W (0 < W <= 10000), indicating that there is a road fro M U to V, with the distance of W.
It is guaranteed, at least one valid arrangement of the tour is existed.
A Blank line was followed after each test case.
Outputfor each test case, output a line with exactly one integer, which are the minimum total distance.
Sample Input
16 91 2 52 3 53 1 103 4 124 1 84 6 115 4 75 6 96 5 4

Sample Output
42



With the expense stream g++ able to pass, C + + will time out.

The KM should be very fast, now brush the cost stream, a few days to make a good km.


Test instructions: Gives the cost of a one-way edge of n points m and passes through each side, allowing you to run out of a Hamiltonian ring (except for the starting point, each point can only walk once) the minimum cost. The topic guarantees that there is at least one ring to satisfy the condition, in fact the inference ring simply needs to infer whether it is full flow.



Idea: Split each point I into left point I and right point i+n
1. The super source point is connected to the left point. Capacity is 1 and the cost is 0
2. All right-click Super sinks with a capacity of 1. Fee is 0
3, each one-way edge--the starting point of the left point of the right point of 1, the cost is the right side.

finally run the cost stream.

Pay attention to the processing of the heavy edge, do not go to the heavy cost stream will time out, there are to be submitted with g++. Take the time to fill the AC code of the KM.

Charge Flow AC Code:

#include <cstdio> #include <cstring> #include <queue> #include <stack> #include <vector>#    Include <algorithm> #define MAXN 400+10#define maxm 70000+10#define INF 0x3f3f3f3fusing namespace Std;struct edge{ int from, to, cap, flow, cost, next;};    Edge Edge[maxm];int HEAD[MAXN], Edgenum;int PRE[MAXN], Dist[maxn];bool vis[maxn];int N, m;int source, Sink;void Init () {    Edgenum = 0; Memset (Head,-1, sizeof (head));} void Addedge (int u, int v, int w, int c)//must go heavy!!!

{int i; for (i = head[u]; I! = 1; i = edge[i].next) {if (edge[i].to = = v) break; } if (i! =-1) {if (Edge[i].cost > c) edge[i].cost = c, edge[i^1].cost =-C; return; } Edge E1 = {u, V, W, 0, C, Head[u]}; Edge[edgenum] = E1; Head[u] = edgenum++; Edge E2 = {V, u, 0, 0,-C, Head[v]}; Edge[edgenum] = E2; HEAD[V] = edgenum++;} void Getmap () {scanf ("%d%d", &n, &m); int A, b, C; Source = 0, sink = 2 * N + 1; Divide each point I into left point I and right point i+n//Super Source point even left point. Capacity is 1 and the cost is 0//All right-click Super Meeting Point. Capacity is 1, cost 0//One-way edge: Starting point left point the right point is 1, the cost is Benquan for (int i = 1; I <= N; i++) Addedge (source, I, 1, 0),//added GE (i, i + N, 1, 0), Addedge (i + N, sink, 1, 0); while (m--) {scanf ("%d%d%d", &a, &b, &c); Addedge (A, b+n, 1, c); }}bool SPFA (int s, int t) {queue<int> Q; memset (Dist, INF, sizeof (Dist)); Memset (Vis, false, sizeof (VIS)); memset (Pre,-1, sizeof (pre)); Dist[s] = 0; Vis[s] = true; Q.push (s); while (! Q.empty ()) {int u = q.front (); Q.pop (); Vis[u] = false; for (int i = head[u]; i =-1; i = Edge[i].next) {Edge E = Edge[i]; if (dist[e.to] > Dist[u] + e.cost && e.cap > E.flow) {dist[e.to] = Dist[u] + e.cos T Pre[e.to] = i; if (!vis[e.to]) {vis[e.to] = true; Q.push (e.to); }}}} ' return pre[t]! =-1;} void MCMF (int s, int t, int &cost, int &flow) {flow = Cost = 0; while (SPFA (s, t)) {int Min = INF; for (int i = pre[t]; i =-1; i = pre[edge[i^1].to]) {Edge E = Edge[i]; min = min (min, e.cap-e.flow); } for (int i = pre[t]; i =-1; i = pre[edge[i^1].to]) {edge[i].flow + = Min; Edge[i^1].flow = Min; Cost + = Edge[i].cost * Min; } flow + = Min; }}int Main () {int t; scanf ("%d", &t); while (t--) {init (); Getmap (); int cost, flow; MCMF (source, sink, cost, flow); printf ("%d\n", cost); } return 0;}


KM algorithm: Heavy brush


Benquan take negative. Pay attention to the processing of the heavy edges.


AC Code:

#include <cstdio> #include <cstring> #include <algorithm> #define INF 0x3f3f3f3f#define MAXN 210using Namespace Std;int Lx[maxn], Ly[maxn];int map[maxn][maxn];bool VISX[MAXN], visy[maxn];int slack[maxn];int Match[MAXN]; int N, m;void getmap () {for (int i = 1; I <= n; i++) {for (int j = 1; J <= N; j + +) Map[i][j]    =-inf;    } int A, b, C;        while (m--) {scanf ("%d%d%d", &a, &b, &c);    if (-C > Map[a][b]) map[a][b] =-C;    }}int DFS (int x) {visx[x] = true;        for (int y = 1; y <= N; y++) {if (visy[y]) continue;        int t = lx[x] + ly[y]-map[x][y];            if (t = = 0) {Visy[y] = true; if (match[y] = =-1 | |                DFS (Match[y])) {match[y] = x;            return 1;    }} else if (Slack[y] > t) slack[y] = t; } return 0;}    void KM () {memset (match,-1, sizeof (match)); memset (ly, 0, sizeof (ly));    for (int x = 1; <= N; x + +) {lx[x] =-inf;    for (int y = 1; y <= N; y++) lx[x] = max (lx[x], map[x][y]);        } for (int x = 1; x <= N; + +) {for (int i = 1; I <= N; i++) slack[i] = INF;            while (1) {memset (VISX, False, sizeof (VISX));            Memset (Visy, False, sizeof (Visy));            if (DFS (x)) break;            int d = INF; for (int i = 1; I <= N; i++) {if (!visy[i] && slack[i] < d) d =            Slack[i];            } for (int i = 1; I <= N; i++) {if (Visx[i]) lx[i]-= D;                } for (int i = 1; I <= N; i++) {if (Visy[i]) ly[i] + = D;            else Slack[i]-= D;    }}} int ans = 0;    for (int i = 1; I <= N; i++) ans + = map[match[i]][i]; printf ("%d\n",-ans);}    int main () {int t;    scanf ("%d", &t);        while (t--) {scanf ("%d%d", &n, &m);        Getmap ();    KM (); } return 0;}


HDOJ 3488 Tour "minimum cost Max Flow" "km algorithm"

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.