直接DP,做完看别人说是用类似于双调欧几里得旅行商问题一样的方法解,仔细一看我的代码,貌似也和那旅行商问题做法差不多~~

这题坑爹之处在于,不能用floyd去优化,也就是说说好了从a到c是99,然后你不能靠先到b再到c来优化。。

View Code
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<queue>
 4 using namespace std;
 5 int cos[50][50],dp[2][33][33][33];
 6 struct data
 7 {
 8     int x,y,z;
 9     data() {}
10     data(int _x,int _y,int _z)
11     {
12         x=_x;
13         y=_y;
14         z=_z;
15     }
16 }Q[200000];
17 int main()
18 {
19     int T;
20     for(scanf("%d",&T); T; T--)
21     {
22         int n;
23         scanf("%d",&n);
24         memset(cos,-1,sizeof(cos));
25         for(int i=1; i<n; i++)
26         {
27             cos[i][i]=0;
28             for(int j=i+1; j<=n; j++)
29             {
30                 scanf("%d",&cos[i][j]);
31                 cos[j][i]=cos[i][j];
32             }
33         }
34         cos[n][n]=0;
35         memset(dp,-1,sizeof(dp));
36         dp[0][1][1][1]=0;
37         int st,ed;
38         st=ed=0;
39         Q[ed++]=data(1,1,1);
40         for(int t=2; t<=n; t++)
41         {
42             int x=t&1,y=x^1;
43             int i=ed;
44             while(st!=i)
45             {
46                 data a=Q[st++];
47                 if(st==200000)
48                     st=0;
49                 int tp=dp[x][a.x][a.y][a.z];
50                 int fp=dp[y][t][a.y][a.z];
51                 if(fp==-1||fp>tp+cos[a.x][t])
52                 {
53                     dp[y][t][a.y][a.z]=tp+cos[a.x][t];
54                     if(fp==-1)
55                     {
56                         Q[ed++]=data(t,a.y,a.z);
57                         if(ed==200000)
58                             ed=0;
59                     }
60                 }
61                 fp=dp[y][a.x][t][a.z];
62                 if(fp==-1||fp>tp+cos[a.y][t])
63                 {
64                     dp[y][a.x][t][a.z]=tp+cos[a.y][t];
65                     if(fp==-1)
66                     {
67                         Q[ed++]=data(a.x,t,a.z);
68                         if(ed==200000)
69                             ed=0;
70                     }
71                 }
72                 fp=dp[y][a.x][a.y][t];
73                 if(fp==-1||fp>tp+cos[a.z][t])
74                 {
75                     dp[y][a.x][a.y][t]=tp+cos[a.z][t];
76                     if(fp==-1)
77                     {
78                         Q[ed++]=data(a.x,a.y,t);
79                         if(ed==200000)
80                             ed=0;
81                     }
82                 }
83             }
84             memset(dp[x],-1,sizeof(dp[x]));
85         }
86         int ans=1<<30,t=(n+1)&1;
87         while(st!=ed)
88         {
89             data tmp=Q[st++];
90             if(st==200000)
91                 st=0;
92             ans=min(ans,dp[t][tmp.x][tmp.y][tmp.z]);
93         }
94         printf("%d\n",ans);
95     }
96     return 0;
97 }