HDU3488 Tour —— 二分图最大权匹配 KM算法
题目链接:https://vjudge.net/problem/HDU-3488
Tour
Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)
Total Submission(s): 3720 Accepted Submission(s): 1777
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.
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.
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
题解:
题意:有n座城市,m条带权有向边。有人想要游历所有城市,于是制定了计划:游历的路径是一个或者多个环,且所有城市都必须仅存在于一个环中。问怎样设计路线使得总路程最短?
我们可以用最大权匹配去求:
1.对于每个点u,我们拆成u和u'。u代表着出点,在二分图的左侧;u'代表着入点,在二分图的右侧。
2.如果有一条有向边u-->v,那么在二分图中,我们加一条边u-->v',并且权值取反。

3.利用KM()算法,求出最大权匹配,再将结果取反,即为答案。
问:为何KM()算法求出来的就一定是一个或多个环呢?
1.可知,题目已经说明了必定有解。那么对应的二分图必定存在完全匹配,完全匹配也必定是最大匹配。
2.我们用KM()算法求出了最大权匹配。根据性质:最大权匹配必定为最大匹配。所以,如果最大匹配是完全匹配,那么最大权匹配也是完全匹配。
3.因为最大权匹配是完全匹配。所以所求出的解必定是一个或多个环。
代码如下:
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int INF = 0x3f3f3f3f;
const LL LNF = 9e18;
const int mod = 1e9+;
const int MAXN = 2e2+; int nx, ny;
int g[MAXN][MAXN];
int linker[MAXN], lx[MAXN], ly[MAXN];
int slack[MAXN];
bool visx[MAXN], visy[MAXN]; bool DFS(int x)
{
visx[x] = true;
for(int y = ; y<=ny; y++)
{
if(visy[y]) continue;
int tmp = lx[x] + ly[y] - g[x][y];
if(tmp==)
{
visy[y] = true;
if(linker[y]==- || DFS(linker[y]))
{
linker[y] = x;
return true;
}
}
else
slack[y] = min(slack[y], tmp);
}
return false;
} int KM()
{
memset(linker, -, sizeof(linker));
memset(ly, , sizeof(ly));
for(int i = ; i<=nx; i++)
{
lx[i] = -INF;
for(int j = ; j<=ny; j++)
lx[i] = max(lx[i], g[i][j]);
} for(int x = ; x<=nx; x++)
{
for(int i = ; i<=ny; i++)
slack[i] = INF;
while(true)
{
memset(visx, , sizeof(visx));
memset(visy, , sizeof(visy)); if(DFS(x)) break;
int d = INF;
for(int i = ; i<=ny; i++)
if(!visy[i])
d = min(d, slack[i]); for(int i = ; i<=nx; i++)
if(visx[i])
lx[i] -= d;
for(int i = ; i<=ny; i++)
{
if(visy[i]) ly[i] += d;
else slack[i] -= d;
}
}
} int res = ;
for(int i = ; i<=ny; i++)
if(linker[i]!=-)
res += g[linker[i]][i];
return res;
} int main()
{
int T, n, m;
scanf("%d", &T);
while(T--)
{
scanf("%d%d", &n,&m);
nx = ny = n;
memset(g, , sizeof(g));
for(int i = ; i<=nx; i++)
for(int j = ; j<=ny; j++)
g[i][j] = -INF;
for(int i = ; i<=m; i++)
{
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
g[u][v] = max(g[u][v], -w);
} printf("%d\n", -KM());
}
}
HDU3488 Tour —— 二分图最大权匹配 KM算法的更多相关文章
- HDU2255 奔小康赚大钱 —— 二分图最大权匹配 KM算法
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2255 奔小康赚大钱 Time Limit: 1000/1000 MS (Java/Others) ...
- 二分图最大权匹配——KM算法
前言 这东西虽然我早就学过了,但是最近才发现我以前学的是假的,心中感慨万千(雾),故作此篇. 简介 带权二分图:每条边都有权值的二分图 最大权匹配:使所选边权和最大的匹配 KM算法,全称Kuhn-Mu ...
- Hdu2255 奔小康赚大钱(二分图最大权匹配KM算法)
奔小康赚大钱 Problem Description 传说在遥远的地方有一个非常富裕的村落,有一天,村长决定进行制度改革:重新分配房子. 这可是一件大事,关系到人民的住房问题啊.村里共有n间房间,刚好 ...
- 二分图 最大权匹配 km算法
这个算法的本质还是不断的找增广路: KM算法的正确性基于以下定理:若由二分图中所有满足A[i]+B[j]=w[i,j]的边(i,j)构成的子图(称做相等子图)有完备匹配,那么这个完备匹配就是二分图的最 ...
- Uvalive 4043 Ants —— 二分图最大权匹配 KM算法
题目链接:https://vjudge.net/problem/UVALive-4043 题意: 给出n个白点和n个黑点的坐标, 要求用n条不相交的线段把他们连接起来,其中每条线段恰好连接一个白点和黑 ...
- hdu 2426 Interesting Housing Problem 最大权匹配KM算法
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2426 For any school, it is hard to find a feasible ac ...
- 网络流——二分图最优匹配KM算法
前言 其实这个东西只是为了把网络流的内容凑齐而写的(反正我是没有看到过这样子的题不知道田忌赛马算不算) 算法过程 我们令左边的点(其实二分图没有什么左右)为女生,右边的点为男生,那么: 为每一个女生定 ...
- “亚信科技杯”南邮第七届大学生程序设计竞赛之网络预赛 A noj 2073 FFF [ 二分图最大权匹配 || 最大费用最大流 ]
传送门 FFF 时间限制(普通/Java) : 1000 MS/ 3000 MS 运行内存限制 : 65536 KByte总提交 : 145 测试通过 : 13 ...
- @noi.ac - 507@ 二分图最大权匹配
目录 @description@ @solution@ @accepted code@ @details@ @description@ 有一天你学了一个能解决二分图最大权匹配的算法,你决定将这个算法应 ...
随机推荐
- 解决hibernate产生的id序列或者setXX不能同步到数据库到问题(this.hibernateTemplate.flush();hibernateTemplate.getSessionFactory().getCurrentSession().connection().commit())
通过WarehouseInventoryPreLog warehouseInventoryPreLog = new WarehouseInventoryPreLog();产生一个id序列 如果不flu ...
- 新建oracle连接远程服务
更新下面两个文件夹中的 D:\app\shisan\product\11.2.0\client_1\network\admin D:\ORACLE\product\11.2.0\dbhome_1\NE ...
- 【Codeforces 449A】Jzzhu and Chocolate
[链接] 我是链接,点我呀:) [题意] 题意 [题解] 设最后行分成了x行,列分成了y列. 那么答案就是floor(n/x)floor(n/y) 然后x+y-2=k //即平均分配x行.y列 我们可 ...
- luogu3415 祭坛
先二分答案转化成判定问题. 考虑拿一根扫描线从 \(x=0\) 扫到 \(x=n\),每次移动扫描线更新每个位置它上面的点数和下面的点数,这样可以确定在当前的扫描线上哪些位置对于 \(y\) 轴方向是 ...
- 大数据学习——linux常用命令(二)
二.目录操作 1 查看目录信息 ls / 查看根目录下的文件信息 ls . 或者 ls ./查看当前目录下的文件信息 ls ../查看根目录下 ls /home/hadoop ls -l . 查看当前 ...
- Oracle臨時表空間過大問題解決
查詢資料庫伺服器時,發現資料庫伺服器磁片使用空間達到了98%,分析總共的資料檔案也不可能達到如此大,經過查詢發現原來臨時表空間的使用方式達到了 32G,導致磁碟空間使用緊張.搜索了相應的文檔與資料後, ...
- hud 2073
#include<stdio.h> #include<math.h> int main() { int i,j,k,n,m,t; double a]; a; for;i++) ...
- Spring Boot配置方式
Spring提供了xml.注解.Java配置.groovy配置实现Bean的创建和注入. 配置元数据 无论xml配置.注解配置还是Java配置,都被称为配置元数据,所谓元数据即描述数据的数据.元数据本 ...
- 洛谷P1258 小车问题
题目描述 甲.乙两人同时从A地出发要尽快同时赶到B地.出发时A地有一辆小车,可是这辆小车除了驾驶员外只能带一人.已知甲.乙两人的步行速度一样,且小于车的速度.问:怎样利用小车才能使两人尽快同时到达. ...
- BZOJ1916: [Usaco2010 Open]冲浪
n<=50000个点m<=150000的带边权DAG,保证1入度0,n出度0,其他点入度出度均不为0,求:从一号点开始到n,期间有可能K<=10次随机选边走,最坏情况下总边权多少. ...