24h購物| | PChome| 登入
2011-05-14 20:47:00| 人氣2,560| 回應2 | 上一篇 | 下一篇

a129. 最小生成樹

推薦 0 收藏 0 轉貼0 訂閱站台

內容 : 

給你一個加權的無向圖(weighted undirected graph),請問這個圖的最小生成樹(minimum spanning tree)的權重和為多少?

輸入說明 :

輸入可能包含多筆測試資料,以EOF作為結束。 

每筆測試資料的第一列有兩個整數n,m(1<=n<=100,000;0<=m<=200,000),代表該圖的點數和邊數。 
頂點的編號從0到n-1。 
接下來有m列,每列用三個整數i,j,c(0<=i,j<n;c為int可儲存的非負整數)描述一條邊,i,j為兩個端點的編號,c為其權重。 

輸出說明 :

對於每筆測試資料,請輸出最小生成樹的權重和。如果圖不連通,請輸出-1。

範例輸入 :help

3 3
1 2 5
2 3 5
3 1 10
4 2
1 2 5
2 3 5

範例輸出 :

10
-1

提示 :

overflow..?

出處 :

(管理:shik)

作法: 并查集

/**********************************************************************************/
/*  Problem: a129 "最小生成樹" from                                          */
/*  Language: C                                                                   */
/*  Result: AC (876ms, 10432KB) on ZeroJudge                                      */
/*  Author: morris1028 at 2011-05-14 20:44:26                                     */
/**********************************************************************************/


#include<stdio.h>
#include<stdlib.h>
int Parent[100001], Rank[100001];
int a, N, M;
void MakeSet(int N) {
    for(a=0;a<=N;a++)
        Parent[a] = a, Rank[a] = 1;
}
int FindSet(int x) {
    if(x!=Parent[x])
        Parent[x] = FindSet(Parent[x]);
    return Parent[x];
}
void Link(int x, int y) {
    if(Rank[x]>Rank[y])
            Parent[y] = x, Rank[x] += Rank[y];
    else
            Parent[x] = y, Rank[y] += Rank[x];
}
int Union(int x, int y) {
    x = FindSet(x), y = FindSet(y);
    if(x != y) {
        Link(x, y);
        return 1;
    }
    return 0;
}
int Input() { 
    char cha; 
    unsigned int x=0; 
    while(cha=getchar()) 
        if(cha!=' '&&cha!='\n' || cha==EOF) break; 
    if(cha==-1) return -1;
    x=cha-48; 
    while(cha=getchar()) { 
        if(cha==' '||cha=='\n') break; 
        x=x*10+cha-48; 
    } 
    return x; 
}
struct Axis{
    int x, y, s;
}Data[400001], X[400001];
void Merge(int, int, int);
void MergeSort(int, int);
main() {
    int T, a, flag;
    long long Ans;
    while(scanf("%d %d",&N, &M) == 2) {
        for(a=0;a<M;a++) {
            Data[a].x = Input(), Data[a].y = Input(), Data[a].s = Input();
            Data[M+a].x = Data[a].x,
            Data[M+a].y = Data[a].y,
            Data[M+a].s = Data[a].s;
        }
        M *= 2;
        MergeSort(0, M-1), MakeSet(N), Ans = 0, flag = 0;
       
        for(a=0;a<M && flag < N;a++)
            if(Union (Data[a].x, Data[a].y) == 1) {
                Ans += Data[a].s, flag ++;
            }
        printf("%lld\n",(flag == N-1)? Ans : -1);
    }
    return 0;
}
void MergeSort(int l, int h) {
    if(l < h) {
        int m=(l+h)/2;
        MergeSort(l  ,m);
        MergeSort(m+1,h);
        Merge(l,m,h);
    }
}
void Merge(int l, int m, int h) {
    int In1=l, In2=m+1;
    int a, b, Top=0;
    while(In1<=m && In2<=h)
        if((Data[In1].s < Data[In2].s))
             X[Top++]=Data[In1++];
       else  X[Top++]=Data[In2++];
    while(In1<=m)   X[Top++]=Data[In1++];
    while(In2<=h)   X[Top++]=Data[In2++];
    for(a=0,b=l;a<Top;a++,b++)
        Data[b]=X[a];
}

台長: Morris
人氣(2,560) | 回應(2)| 推薦 (0)| 收藏 (0)| 轉寄
全站分類: 不分類 | 個人分類: ZeroJudge |
此分類下一篇:a053. Sagit's 計分程式
此分類上一篇:d788. 排名順序

(悄悄話)
2011-11-25 22:42:08
guest
您好,我剛剛發的那一大串程式碼的主人,我突然想到:我如果用悄悄話打,我就看不到東西了,可以請您回覆在這篇嗎?
2011-11-25 22:45:01
是 (若未登入"個人新聞台帳號"則看不到回覆唷!)
* 請輸入識別碼:
請輸入圖片中算式的結果(可能為0) 
(有*為必填)
TOP
詳全文