题意:
ACMer 想要游玩n个城市,告诉我们每个城市间的旅行费用,并且要求每个城市最多走两遍!问最小花费是多少 ?!
做法:用t[S][i]记录每个状态S的每位的数(3进制)
对于每一种状态找到其加一个城市的下一个状态。依次来就可以
网址:http://acm.hdu.edu.cn/showproblem.php?pid=3001
#include<iostream>
using namespace std;
#define inf 0x7f7f7f7f
int n,m;
int map[11][11];
int dp[60000][11];
int t[60000][11];
int s[11];
int main()
{
freopen("in.txt","r",stdin);
int i,j,k;
s[0]=1;
for (i=1;i<11;i++)
s[i]=s[i-1]*3;
for (i=0;i<=s[10];i++)
{
k=i;
for (j=0;j<10;j++)
{
t[i][j]=k%3;
k/=3;
}
}
while (cin>>n>>m)
{
memset(map,0x7f,sizeof(map));
while (m--)
{
scanf("%d%d%d",&i,&j,&k);
i--,j--;
map[i][j]=map[j][i]=min(map[i][j],k);
}
memset(dp,0x7f,sizeof(dp));
int ans=inf;
for (i=0;i<n;i++)
dp[s[i]][i]=0;
for (int S=0;S<s[n];S++)
{
bool istotal=true;
for (i=0;i<n;i++)
{
if (0==t[S][i])
istotal=false;
if (dp[S][i] == inf)
continue;
for (j=0;j<n;j++) if (i!=j && t[S][j]!=2 && map[j][i]!=inf)
dp[S+s[j]][j]=min(dp[S+s[j]][j],dp[S][i]+map[i][j]);
}
if (istotal)
for (i=0;i<n;i++)
ans=min(ans,dp[S][i]);
}
if (ans==inf)
cout<<-1<<endl;
else
cout<<ans<<endl;
}
return 0;
}