题解 | #畅通工程#

畅通工程

http://www.nowcoder.com/practice/4878e6c6a24e443aac5211d194cf3913

一、解题流程:

1. 循环输入城镇和道路数

2. 初始化:

  • 初始化2个数组 father,height(Initial函数)
  • 将所有城镇看为一个独立的个体,此时爸爸是自己,高度为0

3. 输入相连的城镇:

  • (1)查找城镇所在集合即“查找集合根节点”(Find函数)
  • (2)不在同一集合进行合并(Union函数)

4.计算需要的道路数:

  • (1)初始化answer为-1
  • (2)如果全部连通,则集合个数为1,只有根节点的父亲为自己,answer++为0,不需要添加道路
  • (3)如果是两个集合,说明还需要一条路连接这两个集合。有两个根节点的父亲为自己,answer++操作两次,answer=1。以此类推

二、代码如下(C++):

#include<iostream>
using namespace std;
const int MAXN=1000+10;
int father[MAXN];
int height[MAXN];

//初始化,每个城镇是一个独立的个体,爸爸是自己,高度为0
void Initial(int n)   
{
    for(int i=1;i<=n;i++)
    {
        father[i]=i;
        height[i]=0;
    }
    return ;
}

//找根节点,不断的Find(father【i】)
int Find(int x)
{
    if(x!=father[x])
        father[x]=Find(father[x]);  //路径压缩
    return father[x];
}

//合并
void Union(int x,int y)
{
    x=Find(x);  // 找到x的根节点
    y=Find(y);  // 找到y的根节点
    if(x!=y)    // 两个不是一个集合
    {
        if(height[x]<height[y])
            father[x]=y;
        else if(height[x]>height[y])
            father[y]=x;
        else
        {
            father[x]=y;
            height[y]++;
        }
    }
    return ;
}

int main()
{
    int n,m;  // n城镇 m道路
    while(cin>>n>>m) // 循环输入
    {
        if(n==0)     // 输入停止的判断
            break;
        
        Initial(n);  // 初始化所有道路
        while(m--)
        {
            int x,y;
            scanf("%d",&x);
            scanf("%d",&y);
            Union(x, y);  // 将城镇合并
        }
        
        int answer=-1;        // 记录还需要的道路数
        for(int i=1;i<=n;i++) // 循环遍历所有节点,看他们的根节点是否是自己
        {
            if(Find(i)==i)
                answer++;
        }
        printf("%d\n",answer);
    }
    return 0;
}
全部评论

相关推荐

02-18 17:30
腾讯_TEG_技术
多刷**&nbsp;背八股&nbsp;刷面经&nbsp;项目话术准备好&nbsp;不会差的!!!后台看到好多小伙伴们都出现其中一个环节的错误,,,可惜了抓紧机会吧&nbsp;有的是hc&nbsp;但缺的就是稍微用心的人
野猪不是猪🐗:多刷星星,背八股背话术,真的能过你们?对一个个没实习过的学生狂问场景题设计题和底层深挖,别以为我不知道一边说缺人还一边各种kpi面
点赞 评论 收藏
分享
评论
5
收藏
分享

创作者周榜

更多
正在热议
更多
牛客网
牛客企业服务