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. linux基础指令以及权限管理

    基础指令 #打印字符串 echo hello linux #将file1 和 file2粘合在一起,打印到标准输出流 cat file1 file2 标准输入输出 标准输入,stdin,即键盘.鼠标输 ...

  2. java对象中的三种状态和脏检查及刷新缓存机制

    瞬时状态 瞬时状态又称临时状态.如果java对象与数据库中的数据没有任何的关联,即此java对象在数据库中没有相关联的记录,此时java对象的状态为瞬时状态,session对于 瞬时状态的ava对象是 ...

  3. git merge最简洁

    一.开发分支(dev)上的代码达到上线的标准后,要合并到 master 分支 git checkout devgit pullgit checkout mastergit merge devgit p ...

  4. 使用docker安装和运行常用的数据库和中间件

    mysql: docker pull mysql: docker run --name mysql -p : -v /usr/share/zoneinfo/Asia/Shanghai:/etc/loc ...

  5. ElasticSearch 安装配置

    1.   Elasticsearch5.5.2安装 1.1.Elasticsearch安装步骤 #安装之前需安装java 环境,并配置JAVA_HOME环境变量 #直接下载Elasticsearch- ...

  6. Python的scrapy之爬取boss直聘网站

    在我们的项目中,单单分析一个51job网站的工作职位可能爬取结果不太理想,所以我又爬取了boss直聘网的工作,不过boss直聘的网站一次只能展示300个职位,所以我们一次也只能爬取300个职位. jo ...

  7. WebSocket 的使用

    Java 控制台程序实现类似广播功能 服务器端代码 添加 maven 依赖 <dependency> <groupId>javax.websocket</groupId& ...

  8. Git中从远程的分支获取最新的版本到本地——两种命令

    Git中从远程的分支获取最新的版本到本地有这样2个命令: 1. git fetch:相当于是从远程获取最新版本到本地,不会自动merge Git fetch origin master git log ...

  9. 关于 poorpool

    poorpool 真名 chenyixiao.是一条傻逼题都不会做的没有脑子的咸鱼. 山西省临汾第一中学 高二 sx省队里最菜的那一个进队靠暴力. 普通的理科生,曾经爱好数学,然而到了高中发现自己所谓 ...

  10. abtest-system后台系统设计与搭建

    本文来自网易云社区 作者:刘颂 1 项目背景: 2017年5月:客户端提出增加https&dns以及双cdn业务功能 后台配合实现使用disconf配置 针对不同的域名或者请求配置不同的htt ...