在hdu上随便找了一题做,没想到竟然是状态压缩DP。

开始有一句话没看清楚“But Mr Acmer gets bored so easily that he doesn't want to visit a city more than twice!”,我以为每个城市只能访问一次呢,

用二进制怎么搞都不对,上网上搜,都说是三进制,我很不解,这跟三进制有什么关系吗?最后又读了几遍题,把这个错误给发现了。。

三进制思想和二进制一样,只不过多了一种状态,其他的都一样。

题目大意:加限制的最小生成树,限制条件:每个节点最多只能到达两次。

代码:

View Code
 1 #include<stdio.h>
2 # include<string.h>
3 # define INF 0xfffffff
4 int n,m,Min;
5 int adj[12][12];
6 int s[11]={1,3,9,27,81,243,729,2187,6561,19683,59049};
7 int dp[60000][12],dig[60000][12];
8 int min(int a,int b)
9 {
10 return a<b?a:b;
11 }
12 int main()
13 {
14 int i,j,flag,ans,t,k,a,b,c;
15 for(i=0;i<s[10];i++)
16 {
17 t=i;
18 for(j=0;j<10;j++)
19 {
20 dig[i][j]=t%3;
21 t/=3;
22 }
23 }
24 while(scanf("%d%d",&n,&m)!=EOF)
25 {
26 memset(adj,-1,sizeof(adj));
27 for(i=1;i<=m;i++)
28 {
29 scanf("%d%d%d",&a,&b,&c);
30 a--;
31 b--;
32 if(adj[a][b]==-1 || adj[a][b]>c) adj[a][b]=adj[b][a]=c;
33 }
34 for(i=0;i<s[n];i++)
35 {
36 for(j=0;j<n;j++)
37 dp[i][j]=INF;
38 }
39 for(j=0;j<n;j++)
40 dp[s[j]][j]=0;
41 Min=INF;
42 for(i=0;i<s[n];i++)
43 {
44 flag=1;
45 for(j=0;j<n;j++)
46 {
47 if(dig[i][j]==0) flag=0;
48 if(dp[i][j]==INF) continue;
49 for(k=0;k<n;k++)
50 {
51 if(j==k) continue;
52 if(dig[i][k]>=2 || adj[k][j]==-1) continue;
53 ans=i+s[k];
54 dp[ans][k]=min(dp[i][j]+adj[j][k],dp[ans][k]);
55 }
56 }
57 if(flag)
58 {
59 for(j=0;j<n;j++)
60 Min=min(Min,dp[i][j]);
61 }
62 }
63 if(Min==INF) Min=-1;
64 printf("%d\n",Min);
65 }
66 return 0;
67 }
posted on 2011-07-29 11:13  奋斗青春  阅读(739)  评论(0编辑  收藏  举报