求遍历所有点的最短时间。
点是围成一个圈的,所以容易搞。
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <algorithm>
#include <vector>
#include <limits.h>
#include <queue>
#include <stack>
using namespace std;
long long dp[1010][1010][2];
long long a[1010][1010];
int main()
{
int i,cas,t,n,j;
scanf("%d",&t);
cas = 0;
while(cas ++ < t)
{
scanf("%d",&n);
for(i = 1 ;i < n;i ++) {scanf("%I64d",&a[i][i+1]);a[i+1][i] = a[i][i+1];}
scanf("%I64d",&a[n][1]);a[1][n] = a[n][1];
for(i = 1;i <= n;i ++)
{
dp[i][i][0] = 0;
for(j = i +1;j < i+n;j ++)
{
int j1 = j>n?j%n:j;
int j2 = (j-1)>n?(j-1)%n:(j-1);
if(j1 == 0) j1 = n;
if(j2 == 0) j2 = n;
dp[i][j1][0] = dp[i][j2][0] + a[j2][j1];
//cout<<i<<" "<<(j>n?j%n:j)<<" "<<dp[i][j>n?j%n:j][0]<<endl;
//cout<<j<<endl;
//cout<<((j-1)>n?j%n:(j-1))<<" "<<(j>n?j%n:j)<<endl;
}
}
for(i = 1;i <= n;i ++)
{
dp[i][i][1] = 0;
for(j = i+n-1;j >= i+1;j --)
{
int j1 = j>n?j%n:j;
int j2 = (j+1)>n?(j+1)%n:(j+1);
if(j1 == 0) j1 = n;
if(j2 == 0) j2 = n;
dp[i][j1][1] = dp[i][j2][1] + a[j2][j1];
//cout<<i<<" "<<(j>n?j%n:j)<<" "<<dp[i][j>n?j%n:j][1]<<endl;
//cout<<j+1<<endl;
//cout<<((j+1)>n?(j+1)%n:(j+1))<<" "<<(j>n?j%n:j)<<endl;
}
}
int pp = 0;
cout<<"Case #"<<cas<<":";
for(i = 1;i <= n;i ++)
{
long long m = LONG_LONG_MAX;
for(j = i+1;j <i + n;j ++)
{
int j1 = j>n?j%n:j;
int j2 = (j1+1)>n?(j1+1)%n:(j1+1);
if(j1 == 0) j1 = n;
if(j2 == 0) j2 = n;
if(2*dp[i][j1][0] + dp[i][j2][1] < m){ m = 2*dp[i][j1][0] + dp[i][j2][1];}
if(dp[i][j1][0] + 2*dp[i][j2][1] < m){ m = dp[i][j1][0] + 2*dp[i][j2][1];}
}
int j3 = (i+n-1)%n;if(j3 == 0) j3 = n;
int j4 = (i+1)%n;if(j4 == 0) j4 = n;
if(dp[i][j3][0] < m) m = dp[i][j3][0];
if(dp[i][j4][1] < m) m = dp[i][j4][1];
cout<<" "<<m;
}
cout<<endl;
}
}