HDU3488-Tour KM
2016-01-01 03:10
387 查看
Description
In the kingdom of Henryy, there are N (2 <= N <= 200) cities, with M (M <= 30000) one-way roads connecting them. You are lucky enough to have a chance to have a tour in the kingdom. The route should be designed as: The route should contain one or more loops. (A loop is a route like: A->B->……->P->A.)
Every city should be just in one route.
A loop should have at least two cities. In one route, each city should be visited just once. (The only exception is that the first and the last city should be the same and this city is visited twice.)
The total distance the N roads you have chosen should be minimized.
Input
An integer T in the first line indicates the number of the test cases.
In each test case, the first line contains two integers N and M, indicating the number of the cities and the one-way roads. Then M lines followed, each line has three integers U, V and W (0 < W <= 10000), indicating that there is a road from U to V, with the distance of W.
It is guaranteed that at least one valid arrangement of the tour is existed.
A blank line is followed after each test case.
Output
For each test case, output a line with exactly one integer, which is 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
题意:和之前的hdu1853几乎一模一样啊……找若干个环,每个点在且仅在一个环里。
不多说上代码,1853稍微改一下输入输出也是醉了
In the kingdom of Henryy, there are N (2 <= N <= 200) cities, with M (M <= 30000) one-way roads connecting them. You are lucky enough to have a chance to have a tour in the kingdom. The route should be designed as: The route should contain one or more loops. (A loop is a route like: A->B->……->P->A.)
Every city should be just in one route.
A loop should have at least two cities. In one route, each city should be visited just once. (The only exception is that the first and the last city should be the same and this city is visited twice.)
The total distance the N roads you have chosen should be minimized.
Input
An integer T in the first line indicates the number of the test cases.
In each test case, the first line contains two integers N and M, indicating the number of the cities and the one-way roads. Then M lines followed, each line has three integers U, V and W (0 < W <= 10000), indicating that there is a road from U to V, with the distance of W.
It is guaranteed that at least one valid arrangement of the tour is existed.
A blank line is followed after each test case.
Output
For each test case, output a line with exactly one integer, which is 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
题意:和之前的hdu1853几乎一模一样啊……找若干个环,每个点在且仅在一个环里。
不多说上代码,1853稍微改一下输入输出也是醉了
#include<bits/stdc++.h> using namespace std; #define M 310 #define inf 0x3f3f3f3f int nx,ny,n,m; int link[M]; int visx[M],visy[M]; int w[M][M],lx[M],ly[M],slack[M]; int ans[M]; int DFS(int x) { visx[x] = 1; for (int y = 1;y <= ny;y ++) { if (visy[y]) continue; int t = lx[x] + ly[y] - w[x][y]; if (t < 1e-5) { visy[y] = 1; if (link[y] == -1||DFS(link[y])) { link[y] = x; return 1; } } else if (slack[y] > t) slack[y] = t; } return 0; } void KM() { int i,j; memset (link,-1,sizeof(link)); memset (ly,0,sizeof(ly)); memset(lx,0,sizeof(lx)); for (i = 1;i <= nx;i ++) for (j = 1,lx[i] = -inf;j <= ny;j ++) if (w[i][j] > lx[i]) lx[i] = w[i][j]; for (int x = 1;x <= nx;x ++) { for (i = 1;i <= ny;i ++) slack[i] = inf; while (1) { memset (visx,0,sizeof(visx)); memset (visy,0,sizeof(visy)); if (DFS(x)) break; int a=inf; for(int i=1;i<=nx;i++)if(visx[i]) for(int j=1;j<=ny;j++)if(!visy[j]) a=min(a,lx[i]+ly[j]-w[i][j]); for(int i=1;i<=nx;i++){ if(visx[i])lx[i]-=a; if(visy[i])ly[i]+=a; } } } int res = 0,cnt = 0; for(int i = 1;i <= ny;i++) { if(link[i] > -1 && w[link[i]][i] != -inf) res+=w[link[i]][i],cnt++; } if(cnt != ny) printf("-1\n"); else printf("%d\n",-res); } int main() { freopen("h3488.in","r",stdin); int t; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); for(int i = 0;i <= n;i++) { for(int j = 0;j <= n;j++) { w[i][j] = -inf; } } for(int i = 0;i < m;i++) { int u,v,w1; scanf("%d%d%d",&u,&v,&w1); if(-w[u][v] > w1) w[u][v] = -w1; } nx = ny = n; KM(); } return 0; }
相关文章推荐
- 简单的四则运算
- 数的奇偶性
- ACM网址
- 1272 小希的迷宫
- 1272 小希的迷宫
- hdu 1250 大数相加并用数组储存
- 矩阵的乘法操作
- 蚂蚁爬行问题
- 蚂蚁爬行问题
- 求两个数的最大公约数【ACM基础题】
- 打印出二进制中所有1的位置
- 杭电题目---一只小蜜蜂
- 初学图论-Kahn拓扑排序算法(Kahn's Topological Sort Algorithm)
- 初学图论-Bellman-Ford单源最短路径算法
- 初学图论-DAG单源最短路径算法
- 初学图论-Dijkstra单源最短路径算法
- 初学图论-Dijkstra单源最短路径算法基于优先级队列(Priority Queue)的实现
- HDOJ 1002 A + B Problem II (Big Numbers Addition)
- 初学ACM - 半数集(Half Set)问题 NOJ 1010 / FOJ 1207
- 初学ACM - 组合数学基础题目PKU 1833