牛客 旅行
阿新 • • 發佈:2020-09-12
題目描述
輸入描述:
第一行兩個正整數 n,m接下來 m 行,每一行三個正整數 u,v,w 表示 u,v 之間有一條長度為 w 的邊
輸出描述:
示例1輸入
2 1
1 2 3
輸出
3
說明
很顯然,1,2 或者 2,1 都是合法的
備註:
題解:
題目要求構造一個連通圖,使得其中的特定邊權和最大。特定邊權和是即從a1到a2,a2到a3,直到an中所有路徑中最短邊之和。
這裡的特定邊權需要滿足它是路徑中最短的邊,如果有多條可達路徑,取其中所有路徑中最大的最短邊。
首先明確要邊權和最大,所以大的邊應該儘可能被利用,考慮貪心。
我們對邊權進行降序排序,再使用並查集將點與點之間連通起來,使用並查集保證了取邊是兩點路徑中的最小值。
因為其餘點的連通對某一條邊中的兩點的路徑構不成影響,由此我們儘可能的保證了邊權和的最大, 又滿足了
所取的邊是dis要求的兩點之間路徑距離最小的邊。
#include<bits/stdc++.h> using namespace std; const int N=500005; int f[N]; struct node{ int u,v,w; }p[N]; void init(){ for(int i=1;i<=N;i++){ f[i]=i; } } int cmp(node a1,node a2){ return a1.w>a2.w; }int find_(int a){ if(f[a]==a)return a; else return f[a]=find_(f[a]); } int main(){ init(); int n,m;cin>>n>>m; for(int i=1;i<=m;i++){ scanf("%d%d%d",&p[i].u,&p[i].v,&p[i].w); } sort(p+1,p+1+m,cmp); long long ans=0; for(int i=1;i<=m;i++){int t1=find_(p[i].u); int t2=find_(p[i].v); if(t1==t2)continue; f[t1]=t2; ans+=p[i].w; } cout<<ans<<endl; return 0; }