第四天PAT-A1013 Battle Over Cities并查集做法详解

A1013

Description:

战争中,如果城市被占领,则与之相连的所有高速路失效,给出标注出所有高速路的城市地图,求需要维修的高速路数字以让剩余的城市可以连通。

举个例子,如果有三个城市,两条公路分别连接city1-city2,和city1-city3,如果city1被敌军占领,那么我们需要维修一条高速路,即city2-city3。

并查集求集合个数,高速公路数即为集合个数-1

Input:

  • 每个测试一个样例。
  • 每个样例第一行包含三个数字:总城市数N<100,总高速路数M,被占领的城市数K
  • 接下来M行,每行描述了一条高速路,两个数字表示其链接的城市
  • 城市编号从1-N
  • 最后一行包含K个询问,每个询问给出一个数字代表已被占领的城市编号

Output:

  • 分别输出K行给出需要维修的高速公路数
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
#include<algorithm>
#include<map>
#include<vector>
#include<queue>
using namespace std;
const int maxn = 1e3+5;
bool check[maxn];   //用于标志当前节点所属集合是否已访问过
int fa[maxn];   //父节点
int n, m, k;
vector<int>adj[maxn];
int get(int x){ //压缩路径找父节点
    if(fa[x] == x)
        return x;
    return fa[x] = get(fa[x]);
}
void mer(int a, int b){ //合并
    a = get(a);
    b = get(b);
    if(a != b){ //非同一集合才合并
        fa[b] = a;
    }
}
void init(){    //初始化父节点及check数组
    for(int i = 0;i <= n; i++)
        fa[i] = i;
    memset(check, false, sizeof(check));
}
int main()
{
#ifdef ONLINE_JUDGE
#else
    freopen("1.txt", "r", stdin);
#endif // ONLINE_JUDGE
    scanf("%d%d%d", &n, &m, &k);
    int a, b;
    for(int i = 0; i < m; i++){
        scanf("%d%d", &a, &b);
        adj[a].push_back(b);
        adj[b].push_back(a);
    }
    int exceptPoint;
    for(int i = 0; i < k; i++){
        scanf("%d", &exceptPoint);
        init();
        for(int j = 1; j <= n; j++){ //枚举每个点
            if(j == exceptPoint) continue;  //孤岛,所有出度忽略
            for(int edge = 0; edge < adj[j].size(); edge++){
                b = adj[j][edge];
                if(b == exceptPoint) continue;//孤岛,所有入度忽略
                mer(j, b);
            }
        }
        int cnt = 0;
        for(int j = 1; j <= n; j++){
            if(j == exceptPoint) continue;  //孤岛,排斥在所有集合外,不予处理
            if(check[get(j)] == false){ //当前节点所属集合尚未访问过,即为新集合
                cnt++;
                check[get(j)] = true;
            }
        }
        printf("%d\n", cnt-1);
    }
    return 0;
}

版权声明:本文为giggle66原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。