POJ 2404 Jogging Trails

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

时间: 2024-11-04 00:34:07

POJ 2404 Jogging Trails的相关文章

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

[题目链接] http://poj.org/problem?id=2404 [题目大意] 给出一张图,求走遍所有的路径至少一次,并且回到出发点所需要走的最短路程 [题解] 如果图中所有点为偶点,那么一定存在欧拉回路, 否则一定存在偶数个奇点,将这些奇点取出构建新图, 任意两点之间的边权威原图中两点的最短距离, 用状压DP求最小权完美匹配,加上原图所有边权和就是答案. [代码] #include <cstdio> #include <algorithm> #include <c

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

题目:http://poj.org/problem?id=2404 题意:有个n(n<=15)的点和m条无向边,每条边都有自己的权值.现在你要从某个点出发,每条边可以经过多次但要保证每条边至少走一次.现在你要找出一个方案,使得经过所有边的权值和最小,输出最小的权值和. 分析: 首先容易想到的是如果这个图G的每个点的度数都为偶数,那么G是欧拉图,那么一定存在欧拉回路,那么ans=∑每条边权值 如果图G不是欧拉图,那么必有偶数个奇度数的点. 如果我们把每条边都看作有无数条的话,那么原问题就是等价于走

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

题目求从某点出发回到该点经过所有边至少一次的最短行程. 这个问题我在<图论算法理论.实现及应用>中看过,是一个经典的问题——中国邮递员问题(CPP, chinese postman problem)也称为中国邮路问题,是我国数学家管梅谷教授于1962年首次提出的,引起了世界不少数学家的关注.例如1973年匈牙利数学家Edmonds和Johnsom对中国邮路问题提出了一种有效算法. 解决的方法就是通过添加边,使其成为欧拉回路. 而这一题的问题就可以转化给这个无向图加最短的边使其所有点的度位偶数(

图论--欧拉路,欧拉回路(小结)

在题目中在慢慢细说概念 1.HDU - 3018 Ant Trip 题目大意:又N个村庄,M条道路,问需要走几次才能将所有的路遍历 解题思路:这题问的是有关欧拉路的判定 欧拉路就是每条边只能走一次,且要遍历所有的边,简单的说就是一笔画(图连通) 这道题是无向图的欧拉路,无向图的欧拉路的判定:所有点的度数都是偶数度,或者只有两个点的度是奇数度,且图要是连通图 知道欧拉路是什么后,这题就比较好做了,第一件事就是找到有几个连通块,然后再判断一下每个连通块需要几笔才能完成就好了 #include <cs

题单二:图论500

http://wenku.baidu.com/link?url=gETLFsWcgddEDRZ334EJOS7qCTab94qw5cor8Es0LINVaGMSgc9nIV-utRIDh--2UwRLvsvJ5tXFjbdpzbjygEdpGehim1i5BfzYgYWxJmu ==========  以下是最小生成树+并查集=========================[HDU]1213         How Many Tables        基础并查集★1272         小

POJ百道水题列表

以下是poj百道水题,新手可以考虑从这里刷起 搜索1002 Fire Net1004 Anagrams by Stack1005 Jugs1008 Gnome Tetravex1091 Knight Moves1101 Gamblers1204 Additive equations 1221 Risk1230 Legendary Pokemon1249 Pushing Boxes 1364 Machine Schedule1368 BOAT1406 Jungle Roads1411 Annive

HOJ 题目分类

转自:http://blog.sina.com.cn/s/blog_65f3869301011a1o.html ******************************************************************************* 简单题(包括枚举,二分查找,(复杂)模拟,基础数据结构(栈.队列),杂题等 ****************************************************************************

通过ipv6访问 g o o g l e

Google.Youtube.Facebook等均支持IPv6访问,IPv4网络的用户大部分都无法访问,比如Gmail,Google Docs等等各种相关服务.而该类网站大部分均已接入IPv6网络,因此通过IPv6访问则不受任何限制,尤其是对教育网用户来说,使用IPv6更是免费的服务. 而接入IPv6网络,也不仅仅只有教育网用户才能享受,普通公网用户也都可以通过隧道或软件来接入IPv6网络,但根据所处的网络环境.接入方式,访问IPv6的速度通常取决于本地网络宽带提供商与所接入的IPv6隧道服务器

[2016-01-27][POJ][2230][Watchcow]

H - 欧拉图 中级者向 Time Limit:3000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status Practice POJ 2230 Description Bessie's been appointed the new watch-cow for the farm. Every night, it's her job to walk across the farm and make s