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. wordpress整站无损搬迁的几种方法 最后一种最完美

    网站建设之wordpress整站无损搬迁的几种方法 最后一种最完美 网站搬家,当我们更换php虚拟主机,空间升级或更好空间提供商都会发生,站长们请注意,掌握网站迁移方法,是网站日常维护技术中必须掌握的 ...

  2. Git推送到远程分支出错

    执行git push -u origin master fatal: 'git@github.com:qilinonline/git_test.git' does not appear to be a ...

  3. Document .load与Document .ready的区别

    页面加载完成有两种事件 1.load是当页面所有资源全部加载完成后(包括DOM文档树,css文件,js文件,图片资源等),执行一个函数 问题:如果图片资源较多,加载时间较长,onload后等待执行的函 ...

  4. 监听浏览器返回,pushState,popstate 事件,window.history对象

    在WebApp或浏览器中,会有点击返回.后退.上一页等按钮实现自己的关闭页面.调整到指定页面.确认离开页面或执行一些其它操作的需求.可以使用 popstate 事件进行监听返回.后退.上一页操作. 一 ...

  5. Python的virtualenv你用过吗?

    1. 为什么要有virtualenv 在使用 Python 开发的过程中,工程一多,难免会碰到不同的工程依赖不同版本的库的问题: 亦或者是在开发过程中不想让物理环境里充斥各种各样的库,引发未来的依赖灾 ...

  6. python查询mysql数据

    >>>cur.execute("select * from 表名") >>>lines=cur.fetchall() >>>f ...

  7. Python学习手册之Python异常和文件

    在上一篇文章中,我们介绍了 Python 的函数和模块,现在我们介绍 Python 中的异常和文件. 查看上一篇文章请点击:https://www.cnblogs.com/dustman/p/9963 ...

  8. 675. Cut Off Trees for Golf Event

    // Potential improvements: // 1. we can use vector<int> { h, x, y } to replace Element, sortin ...

  9. JavaScript实现判断图片是否加载完成的3种方法整理

    JavaScript实现判断图片是否加载完成的3种方法整理 有时候我们在前端开发工作中为了获取图片的信息,需要在图片加载完成后才可以正确的获取到图片的大小尺寸,并且执行相应的回调函数使图片产生某种显示 ...

  10. R语言绘图:在地图上绘制热力图

    使用ggplot2在地图上绘制热力图 ######*****绘制热力图代码*****####### interval <- seq(0, 150000, 25000)[-2] #设置价格区间 n ...