bestcoder#52 1002 TSP 状压dp
Victor and World
Accepts: 99
Time Limit: 4000/2000 MS (Java/Others)
Memory Limit: 262144/131072 K (Java/Others)
问题描述
经过多年的努力,Victor终于考到了飞行驾照。为了庆祝这件事,他决定给自己买一架飞机然后环游世界。他会驾驶一架飞机沿着规定的航线飞行。在地球上一共有nn个国家,编号从11到nn,各个国家之间通过mm条双向航线连接,第ii条航线连接第u_iui个国家与第v_ivi个国家,通过这条航线需要消耗w_iwi升油,且从11号国家可以直接或间接到达22到nn中任意一个国家。
Victor一开始位于11号国家,他想知道从11号国家出发,经过各个国家至少一次并最后回到11号国家消耗的总油量的最小值是多少。
输入描述
第一行包含一个整数TT,表示测试数据的组数。
每组测试数据的第一行有两个整数nn和mm,表示国家的个数和航线的条数。
接下来mm行,每行三个整数u_iui, v_ivi, w_iwi,描述一条航线。
1leq Tleq 201≤T≤20。
1leq nleq 161≤n≤16。
1leq mleq 1000001≤m≤100000。
1leq w_ileq 1001≤wi≤100。
1leq u_i, v_i leq n1≤ui,vi≤n。
输出描述
每组测试数据输出一行一个整数,即消耗的总油量的最小值。
输入样例
1 3 2 1 2 2 1 3 3
输出样例
10
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<vector> #include<stack> #include<queue> #include<set> #include<map> #include<string> #include<math.h> #include<cctype> #define ll long long #define REP(i,a,b) for(int (i)=(a);(i)<=(b);(i)++) #define REPP(i,a,b,t) for(int (i)=(a);(i)<=(b);(i)+=(t)) #define rep(i,a,b) for(int (i)=(a);(i)>=(b);(i)--) #define repp(i,a,b,t) for(int (i)=(a);(i)>=(b);(i)-=(t)) #define PII pair<int,int> #define fst first #define snd second #define MP make_pair #define PB push_back #define RI(x) scanf("%d",&(x)) #define RII(x,y) scanf("%d%d",&(x),&(y)) #define RIII(x,y,z) scanf("%d%d%d",&(x),&(y),&(z)) #define DRI(x) int (x);scanf("%d",&(x)) #define DRII(x,y) int (x),(y);scanf("%d%d",&(x),&(y)) #define DRIII(x,y,z) int (x),(y),(z);scanf("%d%d%d",&(x),&(y),&(z)) #define RS(x) scanf("%s",x) #define RSS(x,y) scanf("%s%s",x,y) #define DRS(x) char x[maxn];scanf("%s",x) #define DRSS(x,y) char x[maxn],y[maxn];scanf("%s%s",x,y) #define MS0(a) memset((a),0,sizeof((a))) #define MS1(a) memset((a),-1,sizeof((a))) #define MS(a,b) memset((a),(b),sizeof((a))) #define ALL(v) v.begin(),v.end() #define SZ(v) (int)(v).size() using namespace std; const int maxn=20; const int INF=(1<<29); int n,m; int d[maxn][maxn]; int f[1<<maxn][maxn]; int u,v,w; void Init() { REP(i,1,n) REP(j,1,n) d[i][j]=(i==j)?0:INF; } int TSP() { REP(S,0,(1<<n)-1) REP(i,1,n) f[S][i]=INF; f[1][1]=0; REP(S,1,(1<<n)-1){ REP(i,1,n){ if(S&(1<<(i-1))) continue; REP(j,1,n){ if(S&(1<<(j-1))) f[S|(1<<(i-1))][i]=min(f[S][j]+d[j][i],f[S|(1<<(i-1))][i]); } } } int res=INF; REP(i,1,n){ res=min(res,f[(1<<n)-1][i]+d[i][1]); } return res; } int main() { freopen("in.txt","r",stdin); DRI(T); while(T--){ RII(n,m); Init(); while(m--){ RIII(u,v,w); d[u][v]=d[v][u]=min(w,d[u][v]); } REP(k,1,n){ REP(u,1,n){ REP(v,1,n){ d[u][v]=min(d[u][k]+d[k][v],d[u][v]); } } } printf("%d ",TSP()); } return 0; }