1086 - Jogging Trails (欧拉回路+dp)

好长时间没有做dp了 ,做个dp题 ,感觉跟模拟差不多,,这是在倒退啊。。


#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <stack>
#include <algorithm>
#include <cmath>
#include <map>
#define LL long long
#define DB double

using namespace std;
const int N = 16;
const int M = 17009;
const int INF = 0x3f3f3f3f;
int n,m;
int dp[M];
int dis[N][N];
int eg[N];
void floyd()
{
    for(int i=0;i<n;i++)
    for(int j=0;j<n;j++)
    for(int k=0;k<n;k++)
    if(dis[j][k]>dis[j][i]+dis[i][k])
    dis[j][k] = dis[k][j] = dis[j][i]+dis[i][k];
}
int tdis[N][N];
int solve()
{
    int c[N],t=0;
    memset(dp,INF,sizeof(dp));
    dp[0] = 0;
    for(int i=0;i<n;i++) if(eg[i]&1) c[t++] = i;
    if(t==0) return 0;
    for(int i=0;i<t;i++)
    for(int j=0;j<t;j++)
    tdis[i][j] = dis[c[i]][c[j]];
    for(int i=3;i<(1<<t);i++)
    {
        for(int j=0;j<t;j++)
        if(i&(1<<j))
        {
            for(int k=j+1;k<t;k++)
            if(i&(1<<k))
            {
                int t = i-(1<<j)-(1<<k);
                dp[i] = min(dp[i],dp[t]+tdis[j][k]);
            }
        }
    }return dp[(1<<t)-1];
}
int main()
{
    #ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
    #endif
    int cas,T=1;scanf("%d",&cas);
    while(cas--)
    {
        int a,b,c;
        int ans = 0;
        scanf("%d%d",&n,&m);
        memset(dis,INF,sizeof(dis));
        memset(eg,0,sizeof(eg));
        for(int i=0;i<m;i++)
        {
            scanf("%d%d%d",&a,&b,&c);a--;b--;
            if(dis[a][b]>c) dis[a][b]=dis[b][a] = c;
            eg[a]++;eg[b]++;
            ans +=c;
        }
        floyd();
        ans+=solve();
        printf("Case %d: %d\n",T++,ans);
    }
    return 0;
}


你可能感兴趣的:(dp,位压缩)