Tour Time limit:3000/1000 MS (java/others) Memory limit:65535/65535 K (java/others)
Total submission (s): 2308 Accepted Submission (s): 1156
Problem Description in the kingdom of Henryy, there is N (2 <= N <=) cities, with M (M <= 30000) one-way Roa DS 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.
Input an 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.
Output for each test case, output a line with exactly one integer, which are the minimum total distance.
Sample Input
1 6 9 1 2 5 2 3 5 3 1 10 3 4 12 4 1 8 4 6 11 5 4 7 5 6 9 6 5 4
Sample Output
42
Test instructions
Given the one-way edge of n points m and the cost of passing through each side, let you run away from the minimum cost of a Hamiltonian ring (except the starting point, where each point can only walk once). The title guarantees that there is at least one ring to satisfy the condition.
Analytical:
Any similar "forward ring minimum weight override" problem can be written with a minimum cost flow.
Since the topic requires each point to walk at most once, in order to prevent the occurrence of multiple occurrences, we have to split each point I into left point I and right point I + N two points.
The concrete map is as follows:
Source point outset number 0, all left point number 1~n, right point number n+1 ~ 2*n, Meeting point inset number 2*n+1.
(1) The source point outset to the first I point has the edge (outset, I, 1, 0), namely the source point and the left point to build the edge.
(2) If the edge from the I point to the J Point has a value of C, then there is an edge (I, j+n, 1, c), that is, the left and right points are built, ensuring that each point only walks once.
(3) Each node has edges (I+n, inset, 1, 0) to the sink point, that is, the right point and the meeting point are built.
Finally, if the maximum flow = = N (ie full flow), then the minimum cost is what we ask, here the topic to ensure that there is a solution, so the following code I do not judge.
Why this kind of composition method can obtain the solution we want, specific analysis please click here: Analysis
And the subject time requirements more stringent, various timeouts, need to add a go to heavy side processing.
#include <cstdio> #include <cstring> #include <algorithm> #include <queue> #define INF
0X3F3F3F3F #define MAXN #define MAXM 77000 using namespace std;
int n, m;
int outset;//Super Source point int inset;//Super sinks struct Node {int u, V, cap, flow, cost, next;};
Node EDGE[MAXM];
int HEAD[MAXN], CNT;
int per[maxn];//Record The edge of the reach point I on the augmented path number int DIST[MAXN], VIS[MAXN];
void init () {cnt = 0;
Memset (Head,-1, sizeof (head));
} void Add (int u, int v, int w, int c) {int i;
for (i = head[u]; I! =-1; i = Edge[i].next) {node E = Edge[i];
if (v = = e.v) break;
} if (i! =-1) {if (Edge[i].cost > c) edge[i].cost = c, edge[i ^ 1].cost =-C;
return;
}//edge[cnt] = {u, V, W, 0, C, Head[u]} This write is timed out immediately, halo +_+ node E1 = {u, V, W, 0, C, Head[u]};
EDGE[CNT] = E1;
Head[u] = cnt++;
Node E2 = {V, u, 0, 0,-C, Head[v]};
EDGE[CNT] = E2;
HEAD[V] = cnt++; } void Getmap () {scanf ("%d%d", & n, &m);
outset = 0;
Inset = n * 2 + 1;
for (int i = 1; I <= n; ++i) {Add (outset, I, 1, 0);
Add (i + N, inset, 1, 0);
} while (m--) {int A, b, C;
scanf ("%d%d%d", &a, &b, &c);
Add (A, B + N, 1, c); }} bool Spfa (int st, int ed) {queue<int>q;//memset (Dist, INF, sizeof (Dist));//memset (VIS, 0, sizeof (
VIS));
Memset (per,-1, sizeof (per));
for (int i = 0; I <= inset; ++i) {dist[i] = INF;
Vis[i] = 0;
Per[i] =-1;
} Dist[st] = 0;
VIS[ST] = 1;
Q.push (ST);
while (!q.empty ()) {int u = q.front ();
Q.pop ();
Vis[u] = 0;
for (int i = head[u]; i =-1; i = Edge[i].next) {node E = Edge[i]; if (DIST[E.V] > Dist[u] + e.cost && e.cap > E.flow) {//can be relaxed and not full stream dist[e.v] = Dist[u] + e.cos
T
PER[E.V] = i;//record the number of edges that reach this point if (!vis[e.v]) { VIS[E.V] = 1;
Q.push (E.V);
}}}} ' return per[ed]! =-1; } void MCMF (int st, int ed, int &cost, int &flow) {flow = 0;//Total traffic cost = 0;//Total charge while (SPFA (St, ed)) {
Every time you look for the least expensive path int mins = INF;
for (int i = per[ed]; i =-1; i = per[edge[i ^ 1].v]) {mins = min (mins, edge[i].cap-edge[i].flow);
}//augmented for (int i = per[ed]; i =-1; i = per[edge[i ^ 1].v]) {edge[i].flow + = mins;
edge[i ^ 1].flow-= mins;
Cost + = Edge[i].cost * mins;
} flow + = mins;
}} int main () {int T;
scanf ("%d", &t);
while (t--) {init ();
Getmap ();
int cost, flow;
MCMF (outset, inset, cost, flow);
printf ("%d\n", cost);
} return 0;
}