BUPT Summer Journey #test6 A

 

A. 修路 2014新生暑假個人排位賽06

時間限制 3000 ms     內存限制 65536 KB    

題目描述

小弱的學校很喜歡修路,現在給你一張他學校的地圖,地圖上有n個點和m條雙向邊,每條邊代表一條路,這條路有可能是暢通,也有可能正在修路。大家都知道修路使得交通很不方便。所有小弱很想學校快快的把路修好,使得他能夠很輕鬆的到達主樓915去刷題。但考慮到學校的施工能力有限,小弱想讓你幫他算出學校需要集中力量馬上修好的最少路數,使得他能夠從學校任意點出發,在不經過正在施工的路下到達主樓(編號爲1)。

輸入格式

有多組數據。
每組數據以n( 1<=n<=10000), m(1<=m<=200000)開頭。接下來一行有m行數。每行有三個數,對應於u, v, s,分別爲這條路的兩端點(編號從1到n)和路況,s = 0代表暢通, s = 1 代表正在修路。輸入保證圖是連通圖。

 

輸出格式

對每組數據輸出對應的最少路數。

輸入樣例

3 2
1 2 0
1 3 1
3 2
1 2 0
1 3 0
3 2
1 2 1
1 3 1

輸出樣例

1
0
2

 

思路:這道題沒有給出權值,直接就要求你求出最少加的。那最少加的就是每一次先把同一個聯通塊的並在一起,然後若有新的聯通塊就加進去就肯定是最短的。

代碼:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<vector>
#define maxn 20000
#define maxm 500000
//#define LOCAL
using namespace std;
int n,m,x,y,v,cnt,num,ans;
int father[maxn];
int from[maxm],to[maxm];
int getfather(int x)
{
    if(father[x]==x)return x;
    return father[x]=getfather(father[x]);
}
void Union(int x,int y,int v)
{
    int f1=getfather(x);
    int f2=getfather(y);
    if(f1!=f2){num++;if(v==1)ans++;father[f2]=f1;}
}
int main()
{
    #ifdef LOCAL
    freopen("input.txt","r",stdin);
    #endif // LOCAL
    while(scanf("%d%d",&n,&m)==2)
    {
        cnt=0;num=1;ans=0;
        //memset(h,-1,sizeof(h));
        for(int i=1;i<=n;i++)father[i]=i;
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d%d",&x,&y,&v);
            if(v==0)Union(x,y,0);
            else{cnt++;from[cnt]=x;to[cnt]=y;}
        }
        if(cnt==0){printf("0\n");continue;}
        for(int i=1;i<=cnt;i++)
        {
            Union(from[i],to[i],1);
            if(num==n)break;
        }
        printf("%d\n",ans);
    }
    return 0;
}



 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章