Jogging Trails
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 2122   Accepted: 849

Description

Gord is training for a marathon. Behind his house is a park with a large network of jogging trails connecting water stations. Gord wants to find the shortest jogging route that travels along every trail at least once.

Input

Input consists of several test cases. The first line of input for each case contains two positive integers: n <= 15, the number of water stations, and m < 1000, the number of trails. For each trail, there is one subsequent line
of input containing three positive integers: the first two, between 1 and n, indicating the water stations at the end points of the trail; the third indicates the length of the trail, in cubits. There may be more than one trail between any two stations; each
different trail is given only once in the input; each trail can be travelled in either direction. It is possible to reach any trail from any other trail by visiting a sequence of water stations connected by trails. Gord's route may start at any water station,
and must end at the same station. A single line containing 0 follows the last test case.

Output

For each case, there should be one line of output giving the length of Gord's jogging route.

Sample Input

4 5
1 2 3
2 3 4
3 4 5
1 4 10
1 3 12
0

Sample Output

41

Source

Waterloo local 2002.07.01





看的解题报告才懂得,看到有人说KM也能解决,实际实验了一下是不能够的,错误的原因在于我们拆点后,肯定会有对称边,我们希望最大匹配的边也是存在两两对称的,这样最后的结果除以2就能够了,可实际是匹配的边他可能不是对称的,导致了错误



http://www.cnblogs.com/wuminye/archive/2013/05/06/3063902.html

这人写的博客很好,能够借鉴一下

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstdlib>
#include <queue>
#define N 20
#define M 1000000
#define INF 0x7fffff
using namespace std;
int a[N][N],d[N],dis[M];
bool inque[M];
int n,m;
int main()
{
//freopen("data.txt","r",stdin);
int bfs(int x);
while(scanf("%d",&n)!=EOF)
{
if(n==0)
{
break;
}
scanf("%d",&m);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
a[i][j] = INF;
}
}
int res = 0;
memset(d,0,sizeof(d));
for(int i=1;i<=m;i++)
{
int x,y,val;
scanf("%d %d %d",&x,&y,&val);
d[x]++;
d[y]++;
res+=val;
a[x][y] = min(a[x][y],val);
a[y][x] = min(a[y][x],val);
}
for(int k=1;k<=n;k++)
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(i==k||i==j||k==j)
{
continue;
}
a[i][j] = min(a[i][j],a[i][k]+a[k][j]);
}
}
}
int sum=0,db=1;
for(int i=1;i<=n;i++)
{
if(d[i]%2)
{
sum+=db;
}
db = db*2;
}
int ans = bfs(sum);
printf("%d\n",ans+res);
}
return 0;
}
int bfs(int x)
{
memset(inque,false,sizeof(inque));
for(int i=0;i<=((1<<n)-1);i++)
{
dis[i] = INF;
}
queue<int>que;
que.push(x);
inque[x] = true;
dis[x] = 0;
int op[20],op2[20];
op2[0] = 1;
for(int i=1;i<=n;i++)
{
op2[i] = op2[i-1]*2;
}
while(!que.empty())
{
x = que.front();
que.pop();
inque[x] = false;
int xx = x;
for(int i=1;i<=n;i++)
{
op[i] = xx%2;
xx = xx/2;
}
for(int i=1;i<=n;i++)
{
if(op[i])
{
for(int j=i+1;j<=n;j++)
{
if(op[j])
{
int y =x-op2[i-1]-op2[j-1];
if(dis[y]>dis[x]+a[i][j])
{
dis[y] = dis[x]+a[i][j];
if(!inque[y])
{
que.push(y);
inque[y] = true;
}
}
}
}
}
}
}
return dis[0];
}

POJ 2404 Jogging Trails的更多相关文章

  1. POJ 2404 Jogging Trails(最小权完美匹配)

    [题目链接] http://poj.org/problem?id=2404 [题目大意] 给出一张图,求走遍所有的路径至少一次,并且回到出发点所需要走的最短路程 [题解] 如果图中所有点为偶点,那么一 ...

  2. POJ 2404 Jogging Trails [DP 状压 一般图最小权完美匹配]

    传送门 题意:找一个经过所有边权值最小的回路,$n \le 15$ 所有点度数为偶则存在欧拉回路,直接输出权值和 否则考虑度数为奇的点,连着奇数条边,奇点之间走已经走过的路移动再走没走过的路 然后大体 ...

  3. [POJ2404]Jogging Trails

    我太弱了. 我们可以知道一个结论就是对于一个图的话假如所有点的度数都是偶数,那么只需要走一波欧拉回路. 所以我们就把奇点补成偶点. 将两个奇点补充到偶点的最佳方法是选择任意两个奇点连最短路径为权的边 ...

  4. [POJ2404]Jogging Trails(中国旅行商问题)(一般图的匹配——状压DP)

    题目:http://poj.org/problem?id=2404 题意:有个n(n<=15)的点和m条无向边,每条边都有自己的权值.现在你要从某个点出发,每条边可以经过多次但要保证每条边至少走 ...

  5. [UVa10296]Jogging Trails

    题目大意: 中国邮递员问题. 给你一个无向带权连通图,求经过所有边并返回起点的最短路径. 思路: Edmonds-Johnson算法. 显然,当原图为欧拉图时,答案即为其欧拉回路的长度. 考虑原图不存 ...

  6. LightOJ1086 Jogging Trails(欧拉回路+中国邮递员问题+SPFA)

    题目求从某点出发回到该点经过所有边至少一次的最短行程. 这个问题我在<图论算法理论.实现及应用>中看过,是一个经典的问题——中国邮递员问题(CPP, chinese postman pro ...

  7. poj 2404 中国邮递员问题 欧拉回路判定+状压dp

    /* 状压dp 邮递员问题:求经过任意点出发经过每一条边一次并回到原点. 解法:1.如果是欧拉回路那么就是所有的边的总和. 2.一般的解法,找出所有的奇度顶点,任意两个顶点匹配,即最小完美匹配,可用状 ...

  8. lightoj 1086 - Jogging Trails(状压dp)

    题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1086 题解:题目就是求欧拉回路然后怎么判断有欧拉回路只要所有点的度数为偶数.那 ...

  9. 【转】POJ百道水题列表

    以下是poj百道水题,新手可以考虑从这里刷起 搜索1002 Fire Net1004 Anagrams by Stack1005 Jugs1008 Gnome Tetravex1091 Knight ...

随机推荐

  1. 教你怎么用Mono Cecil - 动态注入 (注意代码的注释)

    原文 教你怎么用Mono Cecil - 动态注入 (注意代码的注释) 使用 Mono Cecil 进行反编译:using Mono.Cecil; using Mono.Cecil.Cil; //.. ...

  2. 将 Java Spring Framework 应用程序迁移到 Windows Azure

    我们刚刚发布了一个新教程和示例代码,以阐述如何在Windows Azure中使用 Java 相关技术.在该指南中,我们提供了分步教程,说明如何将 Java Spring Framework 应用程序( ...

  3. 如何修改Sublime 侧边栏Sidebar的颜色

    参考自:http://blog.csdn.net/a497393102/article/details/10563791 首先要找到 Default.sublime-theme 文件, 点击 subl ...

  4. poj 2752 Seek the Name, Seek the Fame(KMP需转换下思想)

    Seek the Name, Seek the Fame Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 10204   Ac ...

  5. Kali Linux 安全渗透教程&lt;第三更&gt;1.2 安全渗透所需工具

    了解了渗透測试的概念后.接下来就要学习进行渗透測试所使用的各种工具.在做渗透測试之前.须要先了解渗透所需的工具.渗透測试所需的工具如表1-1所看到的: 表1-1  渗透所需工具 splint unhi ...

  6. leetcode先刷_Search in Rotated Sorted Array II

    上一页下一页,找到相同的旋转阵列的问题.假设数组元素一再怎么办呢?会发生什么? 我给大家举一个极端的例子.如果是这样的阵列中的元件.1,1,2,1,1,1,1,我们想看看这个数组2,刚开始A[midd ...

  7. android软键盘enter键

    enter键,回车键,电脑键盘上enter键就有多种响应.android软键盘也不例外 你在EditText上输入以后,想在下一行输入框输入,可能需要去点击下一行输入框,让它获取焦点,也可能要隐藏软键 ...

  8. c#关于委托和事件

    using System; using System.Collections.Generic; using System.Text; namespace Delegate {     // 热水器   ...

  9. C程序设计语言之一

    %d 按照十进制整形数打印: %o 按照八进制整形数打印: %x 按照十六进制整形数打印: %c 表示字符 %s 表示字符串 %% 表示%本身打印: %ld long型输出 ”幻数“: #define ...

  10. for循环语句之求和,阶乘,求偶,求n次篮球蹦起高度

    for循环语句格式: ;;/*循环条件*/i++/*状态改变*/) { //循环体,执行代码:(break;跳出循环体) } for 穷举法用循环把各种可能的情况都走一遍,然后用if条件把满足要求的结 ...