實現Runnable和Thread類的區別(建議使用Runnable)
阿新 • • 發佈:2020-07-14
給定一個無向圖,每條邊有一個非負權值。求這個圖中最小生成樹的所有邊的權值之和。生成樹是指包含圖中所有節點的一棵樹,而最小生成樹則指一棵所有邊的權值之和最小的生成樹。
對於30%的資料,m≤10;
對於50%的資料,m≤1000;
對於100%的資料,m≤100000,c≤2000。
輸入
第一行包含兩個數,n和m,其中n為節點數,m為邊數。下面m行,每行三個非負整數a、b和c,a, b<n,表示a和b之間有一條權值為c的邊。輸出
輸出一個數,表示一棵最小生成樹所有邊的權值之和。樣例輸入 Copy
5 8 0 1 1 0 2 2 0 3 5 0 4 7 1 2 0 2 3 15 2 4 25 1 4 100
樣例輸出 Copy
13
提示
對於30%的資料,m≤10;
對於50%的資料,m≤1000;
對於100%的資料,m≤100000,c≤2000。
#include<bits/stdc++.h> using namespace std; typedef long long ll; inline int read() { int x=0;char ch=getchar(); while(ch<'0'||ch>'9')ch=getchar(); while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x; } const int maxn=1e6+100; int pre[maxn],n,m; struct node{ ll u,v,w; }a[maxn]; bool cmp(node x,node y){ return x.w<y.w; } void inint(){ for(int i=0;i<=n;i++){ pre[i]=i; } } int find(int h)//找根? { return pre[h]==h?h:pre[h]=find(pre[h]); }int merge(node n){ int x=find(n.u); int y=find(n.v); if(x!=y){ pre[x]=y; return 1; } return 0; } int main(){ cin>>n>>m; inint(); for(int i=1;i<=m;i++){ a[i].u=read(); a[i].v=read(); a[i].w=read(); } sort(a+1,a+m+1,cmp); ll num=0,ans=0; for(int i=1;i<=m&&num<=n-1;i++) { if(merge(a[i])==1) { num++; ans+=a[i].w; } } printf("%lld\n",ans); }