洛谷 3959 宝藏 NOIP2017提高组Day2 T2

洛谷 3959 宝藏 NOIP2017提高组Day2 T2

洛谷 3959 宝藏 NOIP2017提高组Day2 T2

【题解】

  状压DP. f[i]表示现在的点是否连接的状态是i.

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #define LL long long
 5 #define rg register
 6 #define N 5000
 7 #define inf (0X7f7f7f7f)
 8 using namespace std;
 9 int n,m,ans=2e9,f[N],dis[20],w[N][N];
10 inline int read(){
11     int k=0,f=1; char c=getchar();
12     while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar();
13     while('0'<=c&&c<='9')k=k*10+c-'0',c=getchar();
14     return k*f;
15 }
16 void dfs(int x){
17     for(rg int i=1;i<=n;i++)if(1<<(i-1)&x)
18         for(rg int j=1;j<=n;j++)if(w[i][j]!=inf&&(1<<(j-1)&x)==0)
19             if(f[x|(1<<(j-1))]>f[x]+dis[i]*w[i][j]){
20                 int d=dis[j];
21                 dis[j]=dis[i]+1;
22                 f[x|(1<<(j-1))]=f[x]+dis[i]*w[i][j];
23                 dfs(x|(1<<(j-1)));
24                 dis[j]=d;
25             }
26 }
27 int main(){
28     n=read(); m=read();
29     memset(w,inf,sizeof(w));
30     for(rg int i=1;i<=m;i++){
31         int u=read(),v=read(),d=read();
32         w[u][v]=w[v][u]=min(w[u][v],d);
33     }
34     for(rg int i=1;i<=n;i++){
35         memset(f,inf,sizeof(f));
36         memset(dis,inf,sizeof(dis));
37         dis[i]=1; f[1<<(i-1)]=0;
38         dfs(1<<(i-1));
39         ans=min(ans,f[(1<<n)-1]);
40     }
41     printf("%d
",ans);
42     return 0;
43 }