枚举以每个点为根节点的情况,每次枚举所有与已经开凿出的宝藏屋链接的道路,边权为 w∗(dis[u]+1) 然后最小生成树求解
这么做为什么只能得到 v 相等的部分分啊,不知道思路错在哪了(悲)谢谢各位大佬(
屎山代码
#include<bits/stdc++.h>
#define N 20
using namespace std;
int n,m,cnt,f[N],dis[N],e[N][N];
int ans=91919810;
int find(int x){ return f[x]==x?x:f[x]=find(f[x]); }
struct edge{
int u,v,w;
bool operator<(const edge &x)const{return w>x.w;}
};
priority_queue<edge>q;
void solve(int root){
int res=0,idx=0;
while(!q.empty()) q.pop();
for(int i=1;i<=n;i++) f[i]=i,dis[i]=0;
for(int _=1;_<n;_++){
for(int u=1;u<=n;u++){
if(u!=root&&!dis[u]) continue;//如果当前点不能达到就跳过
for(int v=1;v<=n;v++){
if(v==u||!e[u][v]) continue;
q.push((edge){u,v,(dis[u]+1)*e[u][v]});
}
}
while(!q.empty()){
edge temp=q.top();
q.pop();
int u=temp.u,v=temp.v,w=temp.w;
int uu=find(u),vv=find(v);
if(uu==vv) continue;
f[uu]=vv,res+=w,dis[v]=dis[u]+1;
idx++;
break;
}
}
if(idx==n-1) ans=min(ans,res);//如果正好加了n-1条边就更新答案
}
int main(){
ios::sync_with_stdio(false);
cin>>n>>m;
for(int u=1;u<=n;u++){
for(int v=1;v<=n;v++){
e[u][v]=91919810;
}
}
for(int i=1,u,v,w;i<=m;i++){
cin>>u>>v>>w;
e[u][v]=e[v][u]=min(e[u][v],w);
}
for(int i=1;i<=n;i++) solve(i);//以i为根的树
cout<<ans<<endl;
}