Cyclic Tour

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

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
 
Recommend
lcy   |   We have carefully selected several similar problems for you:  1533 3395 3315 2448 3061 
 

题意:

给一个图,要求用若干个环遍历全部点,求最短路程。

二分匹配KM最小权值做法:

 //46MS    284K    2108 B    C++
/*
二分匹配:
KM算法最小权值模板题...
*/
#include<stdio.h>
#include<string.h>
#define inf 0x7ffffff
int g[][];
int slack[];
int match[];
int lx[],ly[],visx[],visy[];
int n,m;
int Min(int a,int b)
{
return a<b?a:b;
}
int Max(int a,int b)
{
return a>b?a:b;
}
int dfs(int x)
{
visx[x]=;
for(int i=;i<=n;i++){
if(!visy[i]){
if(lx[x]+ly[i]==g[x][i]){
visy[i]=;
if(match[i]==- || dfs(match[i])){
match[i]=x;
return ;
}
}else{
slack[i]=Min(slack[i],lx[x]+ly[i]-g[x][i]);
}
}
}
return ;
}
void KM()
{
memset(match,-,sizeof(match));
for(int i=;i<=n;i++) lx[i]=-inf;
memset(ly,,sizeof(ly));
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
lx[i]=Max(lx[i],g[i][j]);
for(int i=;i<=n;i++){
for(int j=;j<=n;j++)
slack[j]=inf;
while(true){
memset(visx,,sizeof(visx));
memset(visy,,sizeof(visy));
if(dfs(i)) break;
int temp=inf;
for(int j=;j<=n;j++)
if(!visy[j])
temp=Min(temp,slack[j]);
for(int j=;j<=n;j++){
if(visx[j]) lx[j]-=temp;
if(visy[j]) ly[j]+=temp;
else slack[j]-=temp;
}
} }
}
int main(void)
{
int a,b,c;
while(scanf("%d%d",&n,&m)!=EOF)
{
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
g[i][j]=-inf;
for(int i=;i<m;i++){
scanf("%d%d%d",&a,&b,&c);
if(-c>g[a][b])
g[a][b]=-c;
}
KM();
int ans=;
for(int i=;i<=n;i++){
if(match[i]==- || g[match[i]][i]==-inf){
ans=inf;
break;
}
ans+=g[match[i]][i];
}
if(ans==inf) puts("-1");
else printf("%d\n",-ans);
}
return ;
}

最小费用最大流做法:

 //218MS    656K    2377 B    C++
/* 第一题最小费用最大流...基本都是抄= =
注意边的初始化、添加和修改.. */
#include<iostream>
#include<queue>
#define inf 0x7ffffff
#define N 105
using namespace std;
struct node{
int u,v,c,w;
int next;
}edge[*N*N];
int n,m,edgenum,sumflow;
int head[*N],d[*N],pp[*N]; //pp记录增广链
bool vis[*N];
void init() //初始化
{
edgenum=;
memset(head,-,sizeof(head));
}
void addedge(int u,int v,int c,int w) //添加双向边
{
edge[edgenum].u=u;
edge[edgenum].v=v;
edge[edgenum].c=c;
edge[edgenum].w=w;
edge[edgenum].next=head[u];
head[u]=edgenum++;
edge[edgenum].u=v;
edge[edgenum].v=u;
edge[edgenum].c=; //逆向边没流量
edge[edgenum].w=-w; //值取负
edge[edgenum].next=head[v];
head[v]=edgenum++;
}
bool spfa() //求最短路
{
queue<int>Q;
memset(vis,false,sizeof(vis));
memset(pp,-,sizeof(pp));
for(int i=;i<=*(n+);i++) d[i]=inf;
vis[]=true;
d[]=;
Q.push();
while(!Q.empty()){
int u=Q.front();
Q.pop();
vis[u]=false;
for(int i=head[u];i!=-;i=edge[i].next){
int v=edge[i].v;
if(edge[i].c && d[v]>d[u]+edge[i].w){
d[v]=d[u]+edge[i].w;
pp[v]=i;
if(!vis[v]){
Q.push(v);
vis[v]=true;
}
}
}
}
if(d[*n+]==inf) return false;
return true;
}
int MCMF()
{
int t=*n+;
int flow=;
int mincost=;
sumflow=;
while(spfa()){
int minflow=inf+;
for(int i=pp[t];i!=-;i=pp[edge[i].u])
if(edge[i].c<minflow)
minflow=edge[i].c;
flow+=minflow;
for(int i=pp[t];i!=-;i=pp[edge[i].u]){ //调整增广链
edge[i].c-=minflow;
edge[i^].c+=minflow; //逆向边
}
mincost+=d[t]*minflow;
}
sumflow=flow;
return mincost;
}
int main(void)
{
int a,b,c;
while(scanf("%d%d",&n,&m)!=EOF)
{
init();
for(int i=;i<=n;i++){
addedge(,i,,);
addedge(n+i,*n+,,);
}
for(int i=;i<m;i++){
scanf("%d%d%d",&a,&b,&c);
addedge(a,b+n,,c);
}
int ans=MCMF();
if(sumflow!=n) puts("-1");
else printf("%d\n",ans);
}
return ;
}

hdu 1853 Cyclic Tour (二分匹配KM最小权值 或 最小费用最大流)的更多相关文章

  1. hdu 1853 Cyclic Tour 最大权值匹配 全部点连成环的最小边权和

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=1853 Cyclic Tour Time Limit: 1000/1000 MS (Java/Others) ...

  2. hdu 1853 Cyclic Tour 最小费用最大流

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1853 There are N cities in our country, and M one-way ...

  3. HDU 1853 Cyclic Tour[有向环最小权值覆盖]

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

  4. HDU 1853 Cyclic Tour(最小费用最大流)

    Cyclic Tour Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/65535 K (Java/Others) Tota ...

  5. hdu1853 Cyclic Tour (二分图匹配KM)

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

  6. 【刷题】HDU 1853 Cyclic Tour

    Problem Description There are N cities in our country, and M one-way roads connecting them. Now Litt ...

  7. 【HDU 2255】奔小康赚大钱 (最佳二分匹配KM算法)

    奔小康赚大钱 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Subm ...

  8. 最大流增广路(KM算法) HDOJ 1853 Cyclic Tour

    题目传送门 /* KM: 相比HDOJ_1533,多了重边的处理,还有完美匹配的判定方法 */ #include <cstdio> #include <cmath> #incl ...

  9. poj3565 Ants km算法求最小权完美匹配,浮点权值

    /** 题目:poj3565 Ants km算法求最小权完美匹配,浮点权值. 链接:http://poj.org/problem?id=3565 题意:给定n个白点的二维坐标,n个黑点的二维坐标. 求 ...

随机推荐

  1. deepin15.7下使用apt安装mysql5.7不显示root密码设置的解决方法

    在安装MySQL的过程中,并没有要求设置root账户密码的步骤,导致很多人无法使用root账户登录 这个问题早已有解决方案,笔者在deepin15.7下安装也遇到同样问题,只是做一个简单的记录 解决思 ...

  2. JS如何给ul下的所有li绑定点击事件,点击使其弹出下标和内容

    这是一个非常常见的面试题,出题方式多样,但考察点相同,下面我们来看看这几种方法:方法一: var itemli = document.getElementsByTagName("li&quo ...

  3. dns文件

    1.dns简介 dns为域名解析系统,当本地浏览器输入域名访问网站时,如果本地host中没有配置域名与IP的对应关系,那么域名信息将会被发送到dns服务器上,由dns服务器将域名解析为IP(过程较为复 ...

  4. linux课后作业1

    本实验6第一题:菜单驱动程序. 随便进到某个目录,vim driver.sh 把代码写进去. #!/bin/bash function welcome() { echo -e "\n&quo ...

  5. Python3 函数参数

    # # 常规参数 # def jiafa(a,b): # print(a+b) # # jiafa(5,6) # # # def xinxi(name,location,sex='male'): # ...

  6. 50-Identity MVC:DbContextSeed初始化

    1-创建一个可以启动时如果没有一个账号刚创建1个新的账号 namespace MvcCookieAuthSample.Data { public class ApplicationDbContextS ...

  7. easyui combox 随便不存在的值,清空

    onHidePanel: function () { var valueField = $(this).combobox("options").valueField; var va ...

  8. fildder抓包工具详解

    fildder页面介绍名称和含义 名称 含义 # 抓取HTTP Request的顺序,从1开始,以此递增 Result HTTP状态码 Protocol 请求使用的协议,如HTTP/HTTPS/FTP ...

  9. 在Kotlin上怎样用Mockito2 mock final 类(KAD 23)

    作者:Antonio Leiva 时间:Mar 2, 2017 原文链接:https://antonioleiva.com/mockito-2-kotlin/ 如我们在前面文章中谈到的,Kotlin最 ...

  10. Jmeter中传递cookie值

    场景:用户登陆后会本地会保存cookie,cookie是用来跟服务端验证此用户已经登陆过的重要信息,但是如何获取并在其他请求时将此cookie传递给服务器呢? 在线程组下面之直接添加HTTP Cook ...