【DP】 HDU 3001 Travelling 3进制状压

来源:互联网 发布:m905 罗技 mac 编辑:程序博客网 时间:2024/06/14 15:11

变形题

0表示没走过

1表示走过一次

2表示走过两次

#include <cstdio>#include <cstring>#include <cstdlib>#include <string>#include <iostream>#include <algorithm>#include <sstream>#include <cmath>using namespace std;#include <queue>#include <stack>#include <vector>#include <deque>#include <map>#define cler(arr, val)    memset(arr, val, sizeof(arr))typedef long long  LL;const int MAXN = 200000+6;const int MAXM = 240000;const int INF = 0x3f3f3f3f;const int mod = 1000000007;int n,m;int dp[MAXN][10];int mp[14][14],num[13],a[13];int ArrayToInt(int a[]){    int ret=0;    for(int i=n-1;i>=0;i--)    {        ret*=3;        ret+=a[i];    }    return ret;}void intToArray(int x){    for(int i=0;i<n;i++)    {        a[i]=x%3;        x/=3;    }}int main(){#ifndef ONLINE_JUDGE    freopen("in.txt", "r", stdin);    // freopen("out.txt", "w", stdout);#endif    int x,y,c;    num[0]=1;    for(int i=1;i<=11;i++) num[i]=num[i-1]*3;    for(int i=0;i<=10;i++)        printf("%d ",num[i]);    puts("");    while(cin>>n>>m)    {        cler(dp,INF);        for(int i=0;i<=n;i++)            for(int j=0;j<=n;j++) mp[i][j]=INF;        for(int i=0;i<m;i++)        {            scanf("%d%d%d",&x,&y,&c);            y--,x--;            mp[y][x]=mp[x][y]=min(mp[x][y],c);        }        for(int i=0;i<n;i++)            dp[num[i]][i]=0;        int ans=INF;        for(int i=0;i<num[n];i++)        {            for(int u=0;u<n;u++)//现在位置            {                intToArray(i);//得到每位状态                if(a[u]==0) continue;                if(dp[i][u]==INF) continue;                bool flag=true;                for(int t=0;t<n;t++)                    if(a[t]==0)//每位都要走过  0表示没走                        flag=false;                if(flag)ans=min(ans,dp[i][u]);                for(int v=0;v<n;v++)                {                    if(u==v||mp[u][v]==INF||a[v]>=2) continue;                    a[v]++;                    int s=ArrayToInt(a);                    dp[s][v]=min(dp[s][v],dp[i][u]+mp[u][v]);                    a[v]--;                }            }        }        if(ans==INF)            cout<<-1<<endl;        else            cout<<ans<<endl;    }    return 0;}


0 0