Cyclic tour
Time Limit: 1000/1000 MS (Java/others) memory limit: 32768/65535 K (Java/Others)
Total submission (s): 1688 accepted submission (s): 859
Problem descriptionthere are n cities in our country, and m one-way roads connecting them. now little Tom wants to make several cyclic tours, which satisfy that, each cycle contain at least two cities, and each city belongs to one cycle exactly. tom wants the total length of all the tours minimum, but he is too lazy to calculate. can you help him?
Inputthere are several test cases in the input. You shoshould process to the end of file (EOF ).
The first line of each test case contains two integers n (n ≤ 100) and M, indicating the number of cities and the number of roads. the M lines followed, each of them contains three numbers A, B, and C, indicating that there is a road from City A to City B, whose length is C. (1 ≤ a, B ≤ n, A = B, 1 ≤ C ≤ 1000 ).
Outputoutput one number for each test case, indicating the minimum length of all the tours. If there are no such tours, output-1.
Sample input6 91 2 52 3 53 1 103 4 124 1 84 6 115 4 75 6 96 5 46 51 2 12 3 13 4 14 5 15 6 1
Sample Output42-1
HintIn the first sample, there are two cycles, (1-> 2-> 3-> 1) and (6-> 5-> 4-> 6) whose length is 20 + 22 = 42. question: to give a directed right graph, select some edges so that each vertex is in and only in one ring, and require the minimum idea of the edge weight that the weight value passes through:
We can find that the inbound and outbound degrees of each point are 1.
If each point is split into an entry point and an exit point, you can split it into U and U', U is an entry point, and U' is an exit point.
If an edge (u, v) exists, the u '-> V edge
In this way, the entire graph is converted into a bipartite graph. Because an outbound connection is required for each inbound vertex, and an inbound connection is required for each outbound vertex, this is the classic bipartite graph matching problem. Adding a weight value is the problem of optimal matching in a bipartite graph. You can use either the km or the minimum cost stream to solve the problem.
This question got stuck for a few days, because the KM template is connected to every point X and every point y, and this question is only partially connected and does not know how to deal with it.
Later, when the solution is only used to calculate the final answer, if G [linker [y] [Y] =-INF, it will be skipped.
The minimum matching processing is to replace the weight value with a negative one.
I handed in WA for the first time, because I didn't take into account the problem of overlap, I should consider determining the re-Self-ring for these questions.
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#include <vector>#include <map>#include <utility>#include <queue>#include <stack>using namespace std;const int INF=1e9;const double eps=1e-6;const int N = 210;int nx,ny;int g[N][N];int linker[N],lx[N],ly[N];// x is outpoint, y is inpointint slack[N];int visx[N],visy[N];int n,m;bool DFS(int x){ visx[x]=true; for(int y=0;y<ny;y++) { if(visy[y]) continue; int tmp = lx[x]+ly[y]-g[x][y]; if(tmp==0) { visy[y]=true; if(linker[y]==-1||DFS(linker[y])) { linker[y]=x; return true; } } else if(slack[y]>tmp) slack[y]=tmp; } return false;}int KM(){ memset(linker,-1,sizeof(linker)); memset(ly,0,sizeof(ly)); for(int i=0;i<nx;i++) { lx[i]=-INF; for(int j=0;j<ny;j++) if(g[i][j]>lx[i]) lx[i]=g[i][j]; } for(int x=0;x<nx;x++) { for(int i=0;i<ny;i++) slack[i]=INF; while(true) { memset(visx,false,sizeof(visx)); memset(visy,false,sizeof(visy)); if(DFS(x)) break; int d = INF; for(int i=0;i<ny;i++) if(!visy[i] && d>slack[i]) d=slack[i]; for(int i=0;i<nx;i++) if(visx[i]) lx[i]-=d; for(int i=0;i<ny;i++) { if(visy[i]) ly[i]+=d; else slack[i]-=d; } } } int res = 0, cnt = 0; for(int i=0;i<ny;i++) { if(linker[i]==-1 || g[linker[i]][i]==-INF) continue; res += g[linker[i]][i]; cnt++; } if(cnt!=nx) return -1; return -res;}void run(){// memset(g,0,sizeof(g)); for(int i=0;i<n;i++) for(int j=0;j<n;j++) g[i][j]=-INF; int u,v,c; while(m--) { scanf("%d%d",&u,&v); scanf("%d",&c); if(-c>g[u-1][v-1]) g[u-1][v-1]=-c; } nx=ny=n; printf("%d\n",KM());}int main(){ #ifdef LOCAL freopen("case.txt","r",stdin); #endif // LOCAL while(scanf("%d%d",&n,&m)!=EOF) run(); return 0;}
Hdu1853 cyclic Tour (Bipartite Graph Matching km)