Problem Description
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 andn, 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.
For each case, there should be one line of output giving the length of Gord's jogging route.
Sample Input
Sample Output
题意:它让我们经过每条边至少一次,然后回到原点,求可以达到要求的最短的总路径。
所以,这个路径为欧拉回路,欧拉回路要求所有点的入度为偶数。
由于n<15,所以用dis[111111111]来记录状态,1为偶,0为奇。
代码(模仿大神代码写的,原文):
#include <cstdio>
#include <queue>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
using namespace std;
const int maxn = 15+1;
const int maxm = 1<<maxn;
struct Node
{
int pos;//当前的状态
int dist;//当前状态的距离
Node(int pos,int dist)
{
this->pos = pos;
this->dist = dist;
}
//重载小于运算符
bool operator<(const struct Node &ans)const
{
return dist > ans.dist;
}
};
int degree[maxn],edge[maxn][maxn],dis[maxm];
bool vis[maxm];
int n, m, st, ed, sum;
void dijkstra()
{
priority_queue<Node> Q;
int up = 1 << n;
for(int i = 0; i< up;i++)
{
dis[i] = -1;
vis[i] = false;
}
dis[st] = sum;
Q.push(Node(st,dis[st]));
while(!Q.empty())
{
Node ans = Q.top();
Q.pop();
int u = ans.pos;
if(vis[u]) continue;
vis[u] = true;
if(u == ed) break;
for(int i = 0; i <n; i++)
{
for(int j = 0;j < i; j++)
{
if(edge[i][j] != -1)
{
int v = u ^ (1<<i);
v = v ^ (1<<j);
if(dis[v] == -1 || dis[u] + edge[i][j] < dis[v])
{
dis[v] = dis[u] + edge[i][j];
Q.push(Node(v, dis[v]));
}
}
}
}
}
}
int main()
{
while(scanf("%d", &n)!=EOF, n)
{
scanf("%d", &m);
for(int i = 0; i < n; i++)
{
degree[i] = 0;
for(int j = 0; j < n; j++)
edge[i][j] = -1;
}
int a,b,c;
sum = 0;
for(int i = 0;i < m; i++)
{
scanf("%d%d%d", &a, &b, &c);
a--,b--;
degree[a]++;
degree[b]++;
sum += c;
if(edge[a][b] == -1 || edge[a][b] > c)
edge[a][b] = edge[b][a] = c;
}
st = ed = 0;
for(int i = 0; i < n; i++)
{
ed |= (1 << i);
if(degree[i] % 2 == 0)
st |= (1 << i);
}
dijkstra();
printf("%d\n", dis[ed]);
}
return 0;
}