题目地址:http://poj.org/problem?id=3311
从0出发 遍历所有其他城市再回到0,求最短路径和
因为每个城市可以走多次,所以要事先用Floyd算法求出任意两点最短路径
代码如下:
#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<algorithm>
using namespace std;
const int INF=0x3f3f3f3f;
int G[10+5][10+5];
int d[1<<11][11];
int dist[10+5][10+5];
void Floyd(int n)
{
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
dist[i][j]=G[i][j];
for(int k=0;k<n;k++) //中间经过k-1个点
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
dist[i][j]=min(dist[i][j],dist[i][k]+dist[k][j]);
}
int main()
{
int n;
while(cin>>n&&n)
{
for(int i=0;i<=n;i++)
for(int j=0;j<=n;j++)
cin>>G[i][j];
Floyd(n+1);
int t=(1<<(n+1))-1;
int s=1;
memset(d,INF,sizeof(d));
d[s][0]=0;
for(int i=1;i<=t;i+=2) //i 状态 走过的城市
for(int j=0;j<=n;j++) //i-1<<j 到i状态时,最后一步走到(1<<j)那里了
{
if(i&(1<<j))
for(int k=0;k<=n;k++) // 对于i-1<<j状态,最后走到1<<k了
if(j!=k&&(i&(1<<k)))
d[i][j]=min(d[i][j],d[i-(1<<j)][k]+dist[k][j]);
}
int ans=INF;
for(int i=0;i<=n;i++) ans=min(ans,d[t][i]+dist[i][0]);
cout<<ans<<endl;
}
return 0;
}