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;
}



 

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