Victor and World(floyed+状压)

 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5418

题目大意:

T组测试样例,然后n个点,m条边。每一条边的信息是起点,终点,权值(双向图)。

然后问你在每个点都至少访问一次的前提下,最终回到1的最少花费。

具体思路:

dp[i][j]表示在i的二进制中已经访问的点中最终走到 j 的最小花费。

我们在dp的时候,假设要求i -> j  ->k, 最好是第一个for循环跑所有的状态,第二个for循环跑i->j,第三个for循环跑j->k。这样能降低复杂度。

注意这里的Map[u][v]是需要求一个最小值的,我们可以先跑一个floyed预处理出来。或者在dp的时候,把每个点的情况都跑一遍(有点spfa的感觉),这样也能更新出最短距离。

AC代码:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 # define ll long long
 4 # define inf 0x3f3f3f3f
 5 # define ull unsigned long long
 6 const int maxn  = 2e5+100;
 7 const int N = 20;
 8 int Map[N][N];
 9 int dp[maxn][N];
10 int cal(int t)
11 {
12     int ans=0;
13     for(int i=0; i<=16; i++)
14     {
15         if(t&(1<<i))
16             ans++;
17     }
18     return ans;
19 }
20 void floyed(int n)
21 {
22     for(int i=0; i<n; i++)
23     {
24         for(int j=0; j<n; j++)
25         {
26             for(int k=0; k<n; k++)
27             {
28                 Map[j][k]=min(Map[j][k],Map[j][i]+Map[i][k]);
29             }
30         }
31     }
32 }
33 int solve(int n)
34 {
35     int maxstate=(1<<n)-1;
36     for(int i=1; i<=maxstate; i++)
37     {
38         //   for(int w=cal(i); w>=0; w--)
39         //   {
40         for(int j=0; j<n; j++)
41         {
42             if(dp[i][j]==inf)
43                 continue;
44             for(int k=0; k<n; k++)
45             {
46                 if(Map[j][k]==inf)
47                     continue;
48                 dp[i|(1<<k)][k]=min(dp[i|(1<<k)][k],dp[i][j]+Map[j][k]);
49             }
50         }
51     }
52 //   }
53     return dp[maxstate][0];
54 }
55 
56 int main()
57 {
58     int T;
59     scanf("%d",&T);
60     while(T--)
61     {
62         memset(Map,inf,sizeof(Map));
63         memset(dp,inf,sizeof(dp));
64         int n,m;
65         scanf("%d %d",&n,&m);
66         int st,ed,val;
67         for(int i=1; i<=m; i++)
68         {
69             scanf("%d %d %d",&st,&ed,&val);
70             st--,ed--;
71             Map[st][ed]=Map[ed][st]=min(Map[st][ed],val);
72         }
73         floyed(n);
74         dp[1][0]=0;
75         int ans=solve(n);
76         printf("%d\n",ans);
77     }
78     return 0;
79 }
floyed
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 # define ll long long
 4 # define inf 0x3f3f3f3f
 5 # define ull unsigned long long
 6 const int maxn  = 2e5+100;
 7 const int N = 20;
 8 int Map[N][N];
 9 int dp[maxn][N];
10 int cal(int t)
11 {
12     int ans=0;
13     for(int i=0; i<=16; i++)
14     {
15         if(t&(1<<i))
16             ans++;
17     }
18     return ans;
19 }
20 //void floyed(int n)
21 //{
22 //    for(int i=0; i<n; i++)
23 //    {
24 //        for(int j=0; j<n; j++)
25 //        {
26 //            for(int k=0; k<n; k++)
27 //            {
28 //                Map[j][k]=min(Map[j][k],Map[j][i]+Map[i][k]);
29 //            }
30 //        }
31 //    }
32 //}
33 int solve(int n)
34 {
35     int maxstate=(1<<n)-1;
36     for(int i=1; i<=maxstate; i++)
37     {
38         for(int w=cal(i); w>=0; w--)
39         {
40         for(int j=0; j<n; j++)
41         {
42             if(dp[i][j]==inf)
43                 continue;
44             for(int k=0; k<n; k++)
45             {
46                 if(Map[j][k]==inf)
47                     continue;
48                 dp[i|(1<<k)][k]=min(dp[i|(1<<k)][k],dp[i][j]+Map[j][k]);
49             }
50         }
51         }
52     }
53 //   }
54     return dp[maxstate][0];
55 }
56 
57 int main()
58 {
59     int T;
60     scanf("%d",&T);
61     while(T--)
62     {
63         memset(Map,inf,sizeof(Map));
64         memset(dp,inf,sizeof(dp));
65         int n,m;
66         scanf("%d %d",&n,&m);
67         int st,ed,val;
68         for(int i=1; i<=m; i++)
69         {
70             scanf("%d %d %d",&st,&ed,&val);
71             st--,ed--;
72             Map[st][ed]=Map[ed][st]=min(Map[st][ed],val);
73         }
74         //floyed(n);
75         dp[1][0]=0;
76         int ans=solve(n);
77         printf("%d\n",ans);
78     }
79     return 0;
80 }
按点更新

 

posted @ 2019-05-21 16:05  Let_Life_Stop  阅读(271)  评论(0编辑  收藏  举报