LightOJ - 1086 Jogging Trails(欧拉+状态压缩)

来源:互联网 发布:淘宝达人后台 编辑:程序博客网 时间:2024/05/16 02:54

题目大意:有一个人要跑完所有的路,且要跑的路程最短,问如何跑

解题思路:跑完所有的路,且要跑的路程最短,跑欧拉路肯定是最短的。但是给出的图有可能不是欧拉回路,所以得自己再拼凑一下
无向图的欧拉回路就是所有点的度都是偶数了,所以找出所有度为奇数的点,状压求解连接这些点的最短路

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int N = 20;const int INF = 0x3f3f3f3f;const int S = (1 << 15) + 10;int dis[N][N];int degree[N], dp[S];int ans, n, m, cas = 1;void floyd() {    for (int k = 0; k < n; k++)        for (int i = 0; i < n; i++)            for (int j = 0; j < n; j++)                if (dis[i][k] != INF && dis[k][j] != INF && dis[i][j] > dis[i][k] + dis[k][j])                    dis[i][j] = dis[i][k] + dis[k][j];}void init() {    scanf("%d%d", &n, &m);    memset(dis, 0x3f, sizeof(dis));    for (int i = 0; i < n; i++) {        dis[i][i] = 0;        degree[i] = 0;    }    ans = 0;    int u, v, d;    for (int i = 0 ; i < m; i++)  {        scanf("%d%d%d", &u, &v, &d);        ans += d;        u--; v--;        dis[u][v] = dis[v][u] = min(d, dis[u][v]);        degree[u]++;        degree[v]++;    }    floyd();}int dfs(int state) {    if (state == 0) return 0;    if (~dp[state]) return dp[state];    int s;    for (int i = 0; i < n; i++) {        if (state & (1 << i)) {            s = i;            break;        }    }    dp[state] = INF;    for (int i = s + 1; i < n; i++)        if (state & (1 << i))             dp[state] = min(dp[state], dfs(state ^ (1 << s) ^ (1 << i)) + dis[s][i]);    return dp[state];}void solve() {    int state = 0;    for (int i = 0; i < n; i++)        if (degree[i] % 2)  {            state |= (1 << i);        }    memset(dp, -1, sizeof(dp));    ans += dfs(state);    printf("Case %d: %d\n", cas++, ans);}int main() {    int test;    scanf("%d", &test);    while (test--) {        init();        solve();    }    return 0;} 
0 0
原创粉丝点击