hdu1853 Cyclic Tour 完美匹配 验证模版
题意:
给出n个城市和m条路,每个城市只能经过一次,想要旅游所有的城市,求需要的最小花费(路径的长度)。
分析:
做题之前,首先要知道什么是完美匹配。不然题目做了却不知道为什么可以用这个方法来做。完美匹配{X,Y| E},X、Y集合都有n个点(必须相等),它们必须一对一的匹配,并且所有点都要匹配。
对于此题,每个点都有且只有走一次。把每个点都拆为 i与 i'两个点,i值负责出边(就是i点只有出度),i'负责入边。这样就有了两个集合。集合内的点不会有联系。集合之间的点有联系,但是最后只有是一一对应的关系。
也许说得不太明白。明白了,就知道这题什么意思了。发现解题只需要用模版。
建边+ 模版。
由于最佳匹配,求出来的是边的权值和最大的匹配。而这题要求的是权值和最小。有一个常用的方法,把边权改为负的,就是直接加个负号。在模版中,因为不能匹配返回-1,为了一致性,所以改为1。最后得到的值乘以-1就是我们需要的值。
第一次做此题没有理解多少,写了题解(帮助自己理解)也没讲多少。现在重新修改,感觉自己理解得深了。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=, INF=0x3f3f3f3f;
int Map[N][N],mat1[N],mat2[N];//匹配上的左右集合
int KM(int m,int n)
{
int s[N],t[N],a[N],b[N];
int i,j,k,p,q,ans=;
for(i=;i<m;i++)
{
a[i]=-INF;
for(j=;j<n;j++)
a[i]=Map[i][j]>a[i]?Map[i][j]:a[i];
if(a[i]==-INF) return ;//cannot match
}
memset(b,,sizeof(b));
memset(mat1,-,sizeof(mat1));
memset(mat2,-,sizeof(mat2));
for(i=;i<m;i++)
{
memset(t,-,sizeof(t));
p=q=;
for(s[]=i;p<=q&&mat1[i]<;p++)
{
for(k=s[p],j=;j<n&&mat1[i]<;j++)
{
if(a[k]+b[j]==Map[k][j]&&t[j]<)
{
s[++q]=mat2[j]; t[j]=k;
if(s[q]<)
for(p=j;p>=;j=p)
{
mat2[j]=k=t[j];p=mat1[k]; mat1[k]=j;
}
}
}
}
if(mat1[i]<)
{
i--,p=INF;
for(k=;k<=q;k++)
{
for(j=;j<n;j++)
if(t[j]<&&a[s[k]]+b[j]-Map[s[k]][j]<p)
p=a[s[k]]+b[j]-Map[s[k]][j];
}
for(j=;j<n;j++) b[j]+=t[j]<?:p;
for(k=;k<=q;k++) a[s[k]]-=p;
}
}
for(i=;i<m;i++) ans+=Map[i][mat1[i]];
return ans;
}
void init()
{
for(int i=;i<N;i++)
for(int j=;j<N;j++)
Map[i][j]=-INF;
}
int main()
{
//freopen("test.txt","r",stdin);
int n,i,j,m,k;
while(scanf("%d%d",&n,&m)!=EOF)
{
init();
while(m--)
{
scanf("%d%d%d",&i,&j,&k);
i--;j--;k=-k;
Map[i][j]=max(Map[i][j],k);
}
printf("%d\n",-*KM(n,n));
}
return ;
}
hdu1853 Cyclic Tour 完美匹配 验证模版的更多相关文章
- hdu1853 Cyclic Tour (二分图匹配KM)
Cyclic Tour Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/65535 K (Java/Others)Total ...
- HDU1853 Cyclic Tour
Cyclic Tour Time Limi ...
- hdu 1853 Cyclic Tour (二分匹配KM最小权值 或 最小费用最大流)
Cyclic Tour Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/65535 K (Java/Others)Total ...
- HDU1853 Cyclic Tour(最小费用最大流)
题目大概说给一张有向图,每条边都有权值,要选若干条边使其形成若干个环且图上各个点都属于且只属于其中一个环,问选的边的最少权值和是多少. 各点出度=入度=1的图是若干个环,考虑用最小费用最大流: 每个点 ...
- HDU-1853 Cyclic Tour
最小权值环覆盖问题:用几个环把所有点覆盖,求所选取的边最小的权值之和. 拆点思想+求最小转求最大+KM算法 #include <cstdlib> #include <cstdio&g ...
- hdu 1853 Cyclic Tour 最大权值匹配 全部点连成环的最小边权和
链接:http://acm.hdu.edu.cn/showproblem.php?pid=1853 Cyclic Tour Time Limit: 1000/1000 MS (Java/Others) ...
- HDU 3488 Tour (最大权完美匹配)【KM算法】
<题目链接> 题目大意:给出n个点m条单向边边以及经过每条边的费用,让你求出走过一个哈密顿环(除起点外,每个点只能走一次)的最小费用.题目保证至少存在一个环满足条件. 解题分析: 因为要求 ...
- 最大流增广路(KM算法) HDOJ 1853 Cyclic Tour
题目传送门 /* KM: 相比HDOJ_1533,多了重边的处理,还有完美匹配的判定方法 */ #include <cstdio> #include <cmath> #incl ...
- ZOJ-3933 Team Formation (二分图最佳完美匹配)
题目大意:n个人,分为两个阵营.现在要组成由若干支队伍,每支队伍由两个人组成并且这两个人必须来自不同的阵营.同时,每个人都有m个厌恶的对象,并且厌恶是相互的.相互厌恶的人不能组成一支队伍.问最多能组成 ...
随机推荐
- linux中tomcat启动脚本:关闭、发布、重启、测试是否成功
说明 在使用jenkins持续集成时,需要实现自动发布包到tomcat.该脚本实现了在jenkins将包发送到linux服务器上后的自动关闭.发布.启动.测试启动是否成功的过程 思路 该思路以tomc ...
- 如果说需要注册数据中心,这样才能使用demo部署数据中心license证需要申请,使用云之间-工作流程......
如果说需要注册数据中心,这样才能使用demo部署数据中心license证需要申请,使用云之间-工作流程......
- eas启动服务器时非法组件
EAS实例启动报系统中存在非法组件,实例启动失败: 组件检查机制,要求除了 $EAS_HOME eas\server\lib: $EAS_HOME \eas\server\deploy\files ...
- win10家庭版转专业版并激活
之前重装win10的时候没注意,不小心装成家庭版. 本以为家庭版也没什么,后来发现这对程序员来说造成致命打击. 在系统信息页面底部点击“更改密匙”,输入win10升级产品密匙:VK7JG-NPHTM- ...
- eslint 校验去除
不允许对 function 的参数进行重新赋值 /* eslint no-param-reassign: ["error", { "props": false ...
- Java 实现邮件发送功能
1.新建model SendMail.java import java.util.Properties; public class SendMail { // 发送邮件的服务器的IP和端口 priva ...
- C++判断质数
using namespace std; bool isPrimeNum(int n) { if(n<2) return true; for(int i=2;i*i<=n;i++) { i ...
- struts2中<jsp:forward>跳转时报404错误的问题
index.jsp页面: <jsp:forward page="show.action"></jsp:forward> 在struts.x ...
- WebFont与页面font-icon图标研究
当你打开(绝大部分)网站,页面上将会有许多形形色色的小图标(icon),适当的icon的可以达到一图胜千言的目的,使网页的表现效果更佳. 关于页面icon的制作,比较传统的方法是,让设计师去设计一个个 ...
- 第二次训练 密码acmore
网址:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=26733#overview 贪心全场!!!! A题: #include <io ...