HDU - 3001 (dp compresión estado ternario)

Título: el Click
Título: m determinado camino, a través de cada punto de no más de 2, al final de los n puntos de coste mínimo.

n varía de pequeño, los puntos extremos de la carretera n muchos artículos, se pueden enumerar como un punto de inicio o punto final de un estado, ya que el número de cada punto de no más de 2, estado ternaria de compresión.
Se puede reordenar maraña enumeración, ¿por qué puede dirigir a base de asignación que los dos puntos, de un solo cero, porque la ciudad es el punto final del tiempo como uno de los estados de modo transferidos, estado comprimido deben ser incrementales, tan pequeña a gran enumeración y, a continuación, apuntar a enumerar.

#include<cmath>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<istream>
#include<vector>
#include<stack>
#include<set>
#include<map>
#include<algorithm>
#include<queue>
#define inf 0x3f3f3f3f
#define MAX_len 50100*4
using namespace std;
typedef long long ll;
const int mod=100000000;
int a[12][12];
int hh[15];
int num[15];
int dp[12][60048];//第i个城市结尾   j状态   最小花费
int n,m,len;
inline void solve(int s)
{
    while(s)
    {
        hh[++len]=s%3;
        s/=3;
    }
    while(len<n)
    {
        hh[++len]=0;
    }
}
bool check(int s)
{
    int cnt=0;
    while(s)
    {
        if(s%3)
        {
            cnt++;
        }
        s/=3;
    }
    if(cnt==n)
        return true;
    else
        return false;
}
void init()
{
    num[1]=1;
    for(int i=2;i<=10;i++)
    {
        num[i]=num[i-1]*3;
    }
}
int main()
{
    init();
    while(~scanf("%d %d",&n,&m))
    {
        memset(dp,inf,sizeof(dp));
        memset(a,inf,sizeof(a));
        int i,j,k;
        for(i=0;i<m;i++)
        {
            int x,y,val;
            cin>>x>>y>>val;
            if(a[x][y]==inf)
            {
                a[x][y]=val;
                a[y][x]=val;
                int temp=num[x]+num[y];
                dp[x][temp]=a[x][y];
                dp[y][temp]=a[x][y];
            }
            else
            {
                a[x][y]=min(val,a[x][y]);
                a[y][x]=min(val,a[x][y]);
                int temp=num[x]+num[y];
                dp[x][temp]=a[x][y];
                dp[y][temp]=a[x][y];
            }
        }
        for(i=1;i<=n;i++)
        {
            int temp=num[i];
            dp[i][0]=0;
            dp[i][temp]=0;
        }
        int state=pow(3,n);
        for(i=1;i<state;i++)
        {
            len=0;
            solve(i);
            for(j=1;j<=n;j++)
            {
                if(hh[j]==0)
                    continue;
                for(k=1;k<=n;k++)
                {
                    if(hh[k]==2||j==k||a[j][k]==inf)
                        continue;
                    int temp=i+num[k];
                    dp[k][temp]=min(dp[j][i]+a[j][k],dp[k][temp]);
                }
            }
        }
        int ans=inf;
        for(i=1;i<state;i++)
        {
            if(check(i))
            {
                for(j=1;j<=n;j++)
                {
                    ans=min(ans,dp[j][i]);
                }
            }
        }
        if(ans!=inf)
        printf("%d\n",ans);
        else
        printf("-1\n");
    }
    return 0;
}

Publicado 72 artículos originales · ganado elogios 19 · vistas 7492

Supongo que te gusta

Origin blog.csdn.net/weixin_43958964/article/details/105138769
Recomendado
Clasificación