题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1853

Cyclic Tour

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/65535 K (Java/Others)
Total Submission(s): 2289    Accepted Submission(s): 1162

Problem Description
There
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?
 
Input
There are several test cases in the input. You should 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).
 
Output
Output one number for each test case, indicating the minimum length of all the tours. If there are no such tours, output -1.
Sample Input
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
6 5
1 2 1
2 3 1
3 4 1
4 5 1
5 6 1
Sample Output
42
-1

Hint

In the first sample, there are two cycles, (1->2->3->1) and (6->5->4->6) whose length is 20 + 22 = 42.

 
Author
RoBa@TJU
 
Source
 
 
题意:给你n个城市和m条路,现在汤姆想要旅游所有的城市,而且每个城市只能经过一次,当然,旅游路上有一点的花费,现在问汤姆怎么走才能使总花费最小。
分析:刚开始,被题目误导了,说什么跑环啊什么的,好多好多的环啊,我越看越懵逼了。感觉像最小生成树,又没有回来,感觉像一个跑两遍的最短路,一个点又只能经过一次。
其实可以这样思考:
由于图是单向的,每条边的两个点,分别放到入点的集合,和出点的集合,我然后做最小权匹配,然后扫一遍出点,因为要成环,必然每个点既是入点,也是出点。要是每个出点都匹配到了,不管你匹配的点是什么,反正这个环,或者几个环都匹配好了,就返回最小权值,否则返回-1.
然后这里要注意重边,还有,匹配好了,也可能是之前的无穷大,所以加一个判断。
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
const int MAXN = ;
const int INF = 0x3f3f3f3f; int N,NX,NY;
int match[MAXN],lx[MAXN],ly[MAXN],slack[MAXN];
int visx[MAXN],visy[MAXN];
int Map[MAXN][MAXN]; bool FindPath(int u)
{
visx[u] = true;
for(int i = ; i <= NY; ++i)
{
if(visy[i])
continue;
int temp = lx[u] + ly[i] - Map[u][i];
if(temp == )
{
visy[i] = true;
if(match[i] == - || FindPath(match[i]))
{
match[i] = u;
return true;
}
}
else if(slack[i] > temp)
slack[i] = temp;
}
return false;
} int KM()
{
memset(ly,,sizeof(ly));
memset(lx,-,sizeof(lx));
memset(match,-,sizeof(match));
for(int i = ; i <= NX; ++i)
{
for(int j = ; j <= NY; ++j)
if(Map[i][j] > lx[i])
lx[i] = Map[i][j];
} for(int i = ; i <= NX; ++i)
{
for(int j = ; j <= NY; ++j)
slack[j] = INF;
while()
{
memset(visx,,sizeof(visx));
memset(visy,,sizeof(visy));
if(FindPath(i))
break;
int d = INF;
for(int j = ; j <= NY; ++j)
if(!visy[j] && d > slack[j])
d = slack[j];
for(int j = ; j <= NX; ++j)
if(visx[j])
lx[j] -= d;
for(int j = ; j <= NY; ++j)
if(visy[j])
ly[j] += d;
else
slack[j] -= d;
}
} int res = ;
int cnt = ;
for(int i = ; i <= NY; ++i)
if(match[i]!=-&&Map[match[i]][i]!=-INF)
{
res += Map[match[i]][i];
cnt++;
}
if(cnt<NY) return -;
return -res;
} int main()
{ int n,m;
while(~scanf("%d%d",&n,&m))
{
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
Map[i][j] = -INF;
for(int i=;i<m;i++)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
Map[u][v] = max(Map[u][v],-w);
}
NX = NY = n;
printf("%d\n",KM());
}
return ;
}

HDU(1853),最小权匹配,KM的更多相关文章

  1. Poj(3686),最小权匹配,多重匹配,KM

    题目链接 The Windy's | Time Limit: 5000MS | Memory Limit: 65536K | | Total Submissions: 4939 | Accepted: ...

  2. poj 2195(KM求最小权匹配)

    题目链接:http://poj.org/problem?id=2195 思路:我们都知道KM使用来求最大权匹配的,但如果要求最小权匹配,只需把图中的权值改为负值,求一次KM,然后权值和取反即可. ht ...

  3. 【POJ 2400】 Supervisor, Supervisee(KM求最小权匹配)

    [POJ 2400] Supervisor, Supervisee(KM求最小权匹配) Supervisor, Supervisee Time Limit: 1000MS   Memory Limit ...

  4. 【POJ 2195】 Going Home(KM算法求最小权匹配)

    [POJ 2195] Going Home(KM算法求最小权匹配) Going Home Time Limit: 1000MS   Memory Limit: 65536K Total Submiss ...

  5. Assignment (HDU 2853 最大权匹配KM)

    Assignment Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  6. POJ 3565 Ants (最小权匹配)

    题意 给出一些蚂蚁的点,给出一些树的点,两两对应,使他们的连线不相交,输出一种方案. 思路 一开始没想到怎么用最小权匹配--后来发现是因为最小权匹配的方案一定不相交(三角形两边之和大于第三边)--还是 ...

  7. UVALIVE 4970 最小权匹配

    首先贴一下这道题的BNU地址,UVA地址自己找吧. http://acm.bnu.edu.cn/bnuoj/problem_show.php?pid=11852 题意:这道题的意思就是,给你N个棋子的 ...

  8. POJ 2400 最小权匹配

    吐槽:首先,这道题的输入居然是错的.要将上下两个矩阵的位置换一下才可以出样例,也就是上面那个矩阵是employee对Supervisor的打分,下面那个矩阵才是Supervisor对employee的 ...

  9. 二分图带权匹配 KM算法与费用流模型建立

    [二分图带权匹配与最佳匹配] 什么是二分图的带权匹配?二分图的带权匹配就是求出一个匹配集合,使得集合中边的权值之和最大或最小.而二分图的最佳匹配则一定为完备匹配,在此基础上,才要求匹配的边权值之和最大 ...

随机推荐

  1. Lintcode: Count of Smaller Number

    Give you an integer array (index from 0 to n-1, where n is the size of this array, value from 0 to 1 ...

  2. Winform 控件

    ※控件在视图工具箱里面找,找到之后双击即可添加进来,也可以点住拖进来 ※每个工具,控件,窗体都有一个name,相当于id,用来标识该对象的名称,name值不允许重复 控件: 1.Label -- 文本 ...

  3. POJ 1286 Necklace of Beads(Polya原理)

    Description Beads of red, blue or green colors are connected together into a circular necklace of n ...

  4. Spring day01

    1 实例化Spring容器 新建springday01项目1.F盘jar/Spring/first/五个jar包拷贝到lib下,复制xml文件到项目first包下2.First.java测试如何启动容 ...

  5. contentProvider

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools=&q ...

  6. 解决Android抽屉被击穿问题

    1,创建一个抽屉DrawerLayout,在V4包下android.support.v4.widget.DrawerLayout,在要设置抽屉的布局中设置android:layout_gravity= ...

  7. java mybatis 框架下多种类型的参数传入到xml问题

    由于公司要求,最近从.net向java 转,然后过程中遇到各种奇葩问题,特在此随记一番. 场景:一个方法中有两个参数,一个List的集合,一个int 类型的参数,最初我在xml的sql参数,无论定义成 ...

  8. logstash中的redis插件

    redis作为logstash中的官方broker,既有input插件,还有output插件. redis input插件 data_type属性: 有三种类型, list -> BLPOP - ...

  9. 夺命雷公狗—angularjs—21—解决angularjs压缩问题

    我们在实际的开发中往往离不开js的代码压缩,因为这样可以减轻服务器的压力,是的的方法如下所示: <!DOCTYPE html> <html lang="en" n ...

  10. 下拉框分组显示optgroup

    <select> <optgroup label="语言"> <option>中文</option> <option>英 ...