PAT甲级 1013 刷题记录


一、答案

      题目的意思其实可以翻译为:给点一些点和边,去掉某一点及与其相连的边后,该图的连通分支为多少。

#include <iostream>
using namespace std;

int city_root[1000];

int find_root(int i);                                      //寻找根节点函数
void city_root_intialization(int* city_root,int city_num); //各城市结点根节点初始化函数
void connect_city(int i,int j);                            //城市连接函数(合并函数)

int main()
{
    int city_num=0,highway_num=0,check_num=0;
    city_root_intialization(city_root,city_num);           //各城市结点根节点初始化
    cin>>city_num>>highway_num;
    cin>>check_num;
    int** highway;
    highway=new int*[highway_num];
    for(int i=0;i<highway_num;i++){                        //写入道路数据
        highway[i]=new int[2];     
        cin>>highway[i][0]>>highway[i][1];
    }
    for(int i=0;i<check_num;i++){                          //依次遍历需关注的城市
        int occ_city=0;
        cin>>occ_city;
        city_root_intialization(city_root,city_num);
        for(int i=0;i<highway_num;i++){                     //根据公路数据,对各城市进行连接合并,每一群城市由一个城市(根节点城市)代表
            if(highway[i][0]!=occ_city&&highway[i][1]!=occ_city){
                connect_city(highway[i][0],highway[i][1]);
            }
        }

        int* check_group;                                 //判断代表城市数量,得知由城市与公路构成的连通分支数,而需重建的公路为连通分支数-2(被破坏的城市不需要重建公路)
        check_group=new int[city_num];
        city_root_intialization(check_group,city_num);
        for(int k=0;k<city_num;k++){
            check_group[find_root(k)]=0;
        }
        int group_num=0;
        for(int k=0;k<city_num;k++){
            if(check_group[k]==0){
                group_num++;
            }
        }
        cout<<group_num-2<<endl;
    }
    return 0;
}

int find_root(int i)          //寻找父节点函数:不断递归寻找父节点,直至没有父节点
{
    if(city_root[i]==i){
        return i;
    }else{
        city_root[i]=find_root(city_root[i]);  //路径压缩
        return city_root[i];
    }
}

void connect_city(int i,int j) //连接两个城市:将两城市的根节点统一
{
    if(find_root(i)!=find_root(j)){
        city_root[find_root(i)]=find_root(j);
    }
    return;
}

void city_root_intialization(int* city_root,int city_num)  //各城市结点根节点初始化函数
{
    for(int i=0;i<city_num;i++){
        city_root[i]=i;
    }
    return;
}


二、坑点

     要使用并查集和路径压缩,否则最后的测试点没法通过

三、相关知识

      并查集和路径压缩的相关知识可见以下链接:

      算法学习笔记(1) : 并查集

      最后,萌新写文,如有不足,还望指正

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值