为什么可以这样拆点在 这道题 都已经证明过

代码:

  1 //题目上面说了“The only exception is that the first and the last city should be the same and this city is visited twice.”
2 //我还以为是起点要使用两次,没想到题意就是全部点连接之后出入度都为1
3
4 //题意:有n座城市,m条带权有向边。有人想要游历所有城市,于是制定了计划:游历的路径是一个或者多个环,且所有城市都必须仅存在于一个环中。问怎样设计路线使得总路程最短?
5 //我们可以用最大权匹配去求:
6 //1.对于每个点u,我们拆成u和u'。u代表着出点,在二分图的左侧;u'代表着入点,在二分图的右侧。
7 //2.如果有一条有向边u-->v,那么在二分图中,我们加一条边u-->v',并且权值取反。
8 //
9 //3.利用KM()算法,求出最大权匹配,再将结果取反,即为答案。
10 // 举个三个点的例子
11 // p->q`->q->r`->r->p`
12 //
13 //问:为何KM()算法求出来的就一定是一个或多个环呢?
14 //1.可知,题目已经说明了必定有解。那么对应的二分图必定存在完全匹配,完全匹配也必定是最大匹配。
15 //2.我们用KM()算法求出了最大权匹配。根据性质:最大权匹配必定为最大匹配。所以,如果最大匹配是完全匹配,那么最大权匹配也是完全匹配。
16 //3.因为最大权匹配是完全匹配。所以所求出的解必定是一个或多个环。
17 #include<stdio.h>
18 #include<algorithm>
19 #include<string.h>
20 #include<iostream>
21 #include<queue>
22 #include<vector>
23 using namespace std;
24 const int maxn=510;
25 const int INF=0x3f3f3f3f;
26 int n,m;
27 int g[maxn][maxn],link[maxn],matchx[maxn],matchy[maxn];
28 int slack[maxn],visitx[maxn],visity[maxn];
29 int dfs(int x)
30 {
31 visitx[x]=1;
32 for(int i=1;i<=n;++i)
33 {
34 if(visity[i]) continue;
35 int temp=matchx[x]+matchy[i]-g[x][i];
36 if(temp==0)
37 {
38 visity[i]=1;
39 if(link[i]==-1 || dfs(link[i]))
40 {
41 link[i]=x;
42 return 1;
43 }
44 }
45 else slack[i]=min(slack[i],temp);
46 }
47 return 0;
48 }
49 int km()
50 {
51 memset(link,-1,sizeof(link));
52 memset(matchy,0,sizeof(matchy));
53 for(int i=1;i<=n;++i)
54 {
55 matchx[i]=-INF;
56 for(int j=1;j<=n;++j)
57 {
58 matchx[i]=max(matchx[i],g[i][j]);
59 }
60 }
61 for(int x=1;x<=n;++x)
62 {
63 for(int i=1;i<=n;++i)
64 slack[i]=INF;
65 while(1)
66 {
67 memset(visitx,0,sizeof(visitx));
68 memset(visity,0,sizeof(visity));
69 if(dfs(x)) break;
70 int d=INF;
71 for(int i=1;i<=n;++i)
72 if(!visity[i])
73 d=min(d,slack[i]);
74 for(int i=1;i<=n;++i)
75 {
76 if(visitx[i])
77 matchx[i]-=d;
78 }
79 for(int i=1;i<=n;++i)
80 {
81 if(visity[i]) matchy[i]+=d;
82 else slack[i]-=d;
83 }
84 }
85 }
86 int ans=0;
87 for(int i=1;i<=n;++i)
88 {
89 if(link[i]!=-1)
90 ans+=g[link[i]][i];
91 }
92 return ans;
93 }
94 int main()
95 {
96 int t;
97 scanf("%d",&t);
98 while(t--)
99 {
100 scanf("%d%d",&n,&m);
101 memset(g,0,sizeof(g));
102 for(int i=1;i<=n;++i)
103 {
104 for(int j=1;j<=n;++j)
105 {
106 g[i][j]=-INF;
107 }
108 }
109 while(m--)
110 {
111 int u,v,w;
112 scanf("%d%d%d",&u,&v,&w);
113 g[u][v]=max(-w,g[u][v]);
114 }
115 printf("%d\n",-km());
116 }
117 return 0;
118 }

HDU 3488-Tour KM的更多相关文章

  1. Hdu 3488 Tour (KM 有向环覆盖)

    题目链接: Hdu 3488 Tour 题目描述: 有n个节点,m条有权单向路,要求用一个或者多个环覆盖所有的节点.每个节点只能出现在一个环中,每个环中至少有两个节点.问最小边权花费为多少? 解题思路 ...

  2. 图论(二分图,KM算法):HDU 3488 Tour

    Tour Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Total Submis ...

  3. HDU 3488 Tour (最大权完美匹配)【KM算法】

    <题目链接> 题目大意:给出n个点m条单向边边以及经过每条边的费用,让你求出走过一个哈密顿环(除起点外,每个点只能走一次)的最小费用.题目保证至少存在一个环满足条件. 解题分析: 因为要求 ...

  4. HDU - 3488 Tour (KM最优匹配)

    题意:对一个带权有向图,将所有点纳入一个或多个环中,且每个点只出现一次,求其所有环的路径之和最小值. 分析:每个点都只出现一次,那么换个思路想,每个点入度出度都为1.将一个点拆成两个点,一个作为入度点 ...

  5. hdu 3488 Tour

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3488 题意:给你一个N个顶点M条边的带权有向图,要你把该图分成1个或多个不相交的有向环.且所有定点都只 ...

  6. HDU 3488 Tour(最小费用流:有向环最小权值覆盖)

    http://acm.hdu.edu.cn/showproblem.php?pid=3488 题意: 给出n个点和m条边,每条边有距离,把这n个点分成1个或多个环,且每个点只能在一个环中,保证有解. ...

  7. HDU 3488 KM Tour

    参考题解 这题注意有重边.. #include <cstdio> #include <cstring> #include <algorithm> using nam ...

  8. Tour HDU - 3488 有向环最小权值覆盖 费用流

    http://acm.hdu.edu.cn/showproblem.php?pid=3488 给一个无源汇的,带有边权的有向图 让你找出一个最小的哈密顿回路 可以用KM算法写,但是费用流也行 思路 1 ...

  9. hdu 3488(KM算法||最小费用最大流)

    Tour Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Total Submis ...

  10. Tour HDU - 3488(最大权值匹配)

    Tour In the kingdom of Henryy, there are N (2 <= N <= 200) cities, with M (M <= 30000) one- ...

随机推荐

  1. 使用 C# 9 的records作为强类型ID - 路由和查询参数

    上一篇文章,我介绍了使用 C# 9 的record类型作为强类型id,非常简洁 public record ProductId(int Value); 但是在强类型id真正可用之前,还有一些问题需要解 ...

  2. 关于spring-data与elasticsearch的使用,自定义repository

    之前没有使用过spring-data,关于spring-data有很多很棒的设计,例如仅仅只需要声明一个接口就行,你甚至都不需要去实现,spring-data有内置默认的实现类,基本就上完成绝大多数对 ...

  3. 一. SpringCloud简介与微服务架构

    1. 微服务架构 1.1 微服务架构理解 微服务架构(Microservice Architecture)是一种架构概念,旨在通过将功能分解到各个离散的服务中以实现对解决方案的解耦.你可以将其看作是在 ...

  4. 鸿蒙的fetch请求加载聚合数据的前期准备工作-手动配置网络权限

    目录: 1.双击打开"config.json"文件 2.找到配置网络访问权限位置1 3.配置内容1 4.默认访问内容是空的 5.添加配置内容2 6.复制需要配置的网络二级URL 7 ...

  5. 入门OJ:郭嘉的消息传递

    题目描述 我们的郭嘉大大在曹操这过得逍遥自在,但是有一天曹操给了他一个任务,在建邺城内有N(<=1000)个袁绍的奸细 将他们从1到N进行编号,同时他们之间存在一种传递关系,即若C[i,j]=1 ...

  6. 干电池1.5V升压3.3V芯片电路图

    1.5V升压3.3V的芯片 PW5100 是一款大效率.10uA低功耗.低纹波.高工作频率1.2MHZ的 PFM 同步升压 DC/DC 变换器.输入电压可低0.7V,输入电压范围0.7V-5V之间,输 ...

  7. yml文件中${DB_HOST:localhost}的含义

    引自:https://blog.csdn.net/chen462488588/article/details/109057342 今天学习eladmin项目中看到application-dev.yml ...

  8. watchdog应用实例

    watchdog应用实例 By 鬼猫猫 20130504 http://www.cnblogs.com/muyr/ 实例:监测某文件夹,一旦文件夹里有文件,就把它剪切到其他服务器 import sys ...

  9. css animation @keyframes 动画

    需求:语音播放动态效果 方案:使用如下图片,利用 css animation @keyframes  做动画 html <span class="horn" :class=& ...

  10. JavaScript中原型对象的应用!

    JavaScript中原型对象的应用! 扩展内置对象的方法 我以数组对象为例! // 原型对象的应用 扩展内置对象方法! Array.prototype.sum = function() { var ...