LightOJ

来源:互联网 发布:网络歌手沫沫酱照片 编辑:程序博客网 时间:2024/05/02 04:45

思路:欧拉回路中所有点的度为偶数,然后剩下奇数的点用状压DP找最短路即可。

#include <stdio.h>#include <string.h>#include <ctime>#include <stack>#include <string>#include <algorithm>#include <iostream>#include <cmath>#include <map>#include <queue>#include <vector>using namespace std;#define LL long long#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define lowbit(x) (x&-x)const int maxn = 17;const int INF = 0x3f3f3f3f;int dis[maxn][maxn];int in[maxn],dp[1<<maxn];int n,m;void floyd(){    for(int k=0; k<n; k++)        for(int i=0; i<n; i++)            for(int j=0; j<n; j++)    {        dis[i][j] = min(dis[i][j],dis[i][k]+dis[k][j]);    }}int main(){    int T,cas=1;    scanf("%d",&T);    while(T--)    {        scanf("%d%d",&n,&m);        memset(dis,INF,sizeof(dis));        memset(in,0,sizeof(in));        int sum = 0;        for(int i=0; i<m; i++)        {            int u,v,c;            scanf("%d%d%d",&u,&v,&c);            u--,v--;            dis[u][v] = dis[v][u] = min(dis[u][v],c);            sum += c;            in[u]++,in[v]++;        }        floyd();        int p = 0;        for(int i=0; i<n; i++)        {            if(in[i]&1)                p |= (1<<i);        }        memset(dp,INF,sizeof(dp));        dp[p] = sum;        for(int i=p; i; i--)        {            for(int j=0; j<n; j++)            {                if(!(i&(1<<j))) continue;                for(int k=0; k<n; k++)                {                    if(j==k || !(i&(1<<k))) continue;                    dp[i^(1<<j)^(1<<k)] = min(dp[i^(1<<j)^(1<<k)],dp[i]+dis[j][k]);                }            }        }        printf("Case %d: %d\n",cas++,dp[0]);    }return 0;}


0 0
原创粉丝点击