Victor and World
题意:求从一号城市出发经过所有城市,然后再返回一号城市所用的燃料最少。
题解:我用Floyd处理出任意两个点之间的最短路。然后设状压dp[i][j],代表第i个城市经过城市的状态由j来代表,那么怎么转移呢?具体看代码实现。
关键就是三层for,第一层for代表经过城市的所有状态,第二层for代表该状态下最后到达的点的位置,最后一层代表我可以再到达的一个新的点。
#include<bits/stdc++.h>
using namespace std;
int dist[20][20],dp[20][(1<<16)+10];
int inf = 1e9+10;
int n;
void floyd()
{
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(dist[i][j]>dist[i][k]+dist[k][j])
dist[i][j] = dist[i][k] + dist[k][j];
}
int main()
{
int t;scanf("%d",&t);
while(t--)
{
int m; scanf("%d%d",&n,&m);
int u,v,w;
for(int i=0;i<20;i++) for(int j=0;j<20;j++) dist[i][j] = inf ;
for(int i=0;i<20;i++) for(int j=0;j<=(1<<16);j++) dp[i][j] = inf ;
for(int i=1;i<=m;i++){
scanf("%d%d%d",&u,&v,&w);
dist[u][v] = dist[v][u] = min(dist[u][v],w);
}
floyd();
dp[1][1] = 0;
for(int s=1;s<(1<<n);s++)
for(int j=1;(1<<(j-1))<=s;j++)
if((s>>j-1)&1)
{
for(int k=1;k<=n;k++)
{
int s0 = s|(1<<(k-1));
dp[k][s0] = min(dp[k][s0],dp[j][s]+dist[j][k]);
}
}
printf("%d\n",dp[1][(1<<n)-1]);
}
}