HDU3001 Travelling

来源:互联网 发布:国泰安经济金融数据库 编辑:程序博客网 时间:2024/05/19 22:44

题意:一个去旅行,要求花费最小走完所有的城市,可以选择任意一个城市出发,有个限制条件,每个城市最多能走两次。。

如果只用2进制表示,只能表示这个城市走过没有,所以我想不到做法。。

正确的做法是用3进制,每一位就可以表示走过这个城市的次数(2次以上也算做两次),所以先事先处理出没有3进制能表示的状态,然后枚举这些状态,如果这个状态中存在一个城市为0,就代表这个状态不行(flag=0)。。

/*************************************************************************> File Name: 3001.cpp> Author: tjw> Mail: > Created Time: 2014年11月10日 星期一 17时54分08秒 ************************************************************************/#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#include<queue>#include<vector>#include<stack>#include<map>#define ll long long#define ls k<<1#define rs k<<1|1using namespace std;const int MAXN=600000;const int INF=1<<30;int bit[11]={1,3,9,27,81,243,729,2187,6561,19683,59049};int dp[MAXN][12];int num[MAXN][12];int mp[10][10];void init(){    int i,j;    for(i=0;i<bit[10];i++)    {        int temp=i;        for(j=0;j<10;j++)        {            num[i][j]=temp%3;            temp=temp/3;        }    }}int main(){    int n,m,u,v,c,i,j,k;    init();    while(scanf("%d%d",&n,&m)==2)    {        memset(mp,-1,sizeof(mp));        while(m--)        {            scanf("%d%d%d",&u,&v,&c);            u--;            v--;            if(mp[u][v]==-1||mp[u][v]>c)                mp[u][v]=mp[v][u]=c;        }        for(i=0;i<bit[n];i++)        {            for(j=0;j<n;j++)                dp[i][j]=INF;        }        for(i=0;i<n;i++)            dp[bit[i]][i]=0;        int ans=INF;        for(i=0;i<bit[n];i++)        {            int flag=1;            for(j=0;j<n;j++)            {                if(num[i][j]==0)                    flag=0;                if(dp[i][j]==INF)                    continue;                for(k=0;k<n;k++)                {                    if(mp[j][k]==-1||j==k||num[i][k]>=2)                        continue;                    int temp=i+bit[k];                    dp[temp][k]=min(dp[temp][k],dp[i][j]+mp[j][k]);                }            }            if(flag)            {                for(j=0;j<n;j++)                    ans=min(ans,dp[i][j]);            }        }        if(ans==INF)            ans=-1;        printf("%d\n",ans);    }    return 0;}


0 0