NOIP2017 寶藏
阿新 • • 發佈:2020-09-15
樹上的旅行商問題
#include<bits/stdc++.h> #define ll long long #define inf 1000000000 #define N 15 using namespace std; int dist[N][N],dis[N],flag[N][N],dp[1<<13],n,m; inline int read() { int f=1,x=0;char s=getchar(); while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();} while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();} x*=f; return x; } void dfs(int x) { for(int i=1;i<=n;i++) if((1<<(i-1))&x) //i在我們所走過的點的集合中 for(int j=1;j<=n;j++) //j不在我們走過的集合中 if(!(1<<(j-1)&x)&&flag[i][j]) //並且i可以走到j if(dp[1<<(j-1)|x]>dp[x]+dis[i]*dist[i][j]) { int t=dis[j]; dis[j]=dis[i]+1; dp[1<<(j-1)|x]=dp[x]+dis[i]*dist[i][j]; dfs(1<<(j-1)|x); dis[j]=t; } } int main() { n=read(),m=read(); int ans=inf; memset(dist,0x3f,sizeof(dist)); for(int i=1;i<=m;i++) { int x=read(),y=read(),z=read(); flag[x][y]=1; flag[y][x]=1; dist[x][y]=min(dist[x][y],z); dist[y][x]=min(dist[y][x],z); } for(int i=1;i<=n;i++) //列舉下最開始的點是哪一個 { memset(dis,0x3f,sizeof(dis)); memset(dp,0x3f,sizeof(dp)); dis[i]=1; dp[1<<(i-1)]=0; dfs(1<<(i-1)); ans=min(ans,dp[(1<<n)-1]); } printf("%d",ans); return 0; }