PAT 1013 Battle Over Cities

题目描述

英文

PAT 1013 Battle Over Cities_第1张图片

中文大意

给定一个城市图,指出多少条高速公路需要被修复
举例:有3个城市 c1, c2, c3 2条公路连接 c1, c2c1, c3
如果把c1 从图中移去,我们就需要修复 1 条公路来连接 c2, c3

输入
第一行包含 3个数字:N(<1000), M, K
N:城市数量
M:剩余公路数量
K:被检查城市数量
接下来的 M 行用两个整数描述 高速公路
最后一行包含 K 个数字,展示了我们在意的城市节点
输出
对于 K 个城市而言,如果这个城市节点丢失了,在一行内输出我们书要修复多少条公路

样例

PAT 1013 Battle Over Cities_第2张图片

思路分析

把题目抽象化,其实就是一个图,然后把图中的某一点,抽掉
问:剩余的图需要添加多少条边,才能变成连通的?
使用DFS深度优先遍历,计算剩余节点有几个独立区域,然后再添加边 把这几个独立区域连接起来
原理:如果图是连通的,那么DFS一定可以把图全部搜索完毕
否则,需要 构建公路(也就是边edge) ,且边的数量为 独立区域数量 减一

code

#include 
#include 
#define NumOfNode 1001

using namespace std;

int edge[NumOfNode][NumOfNode];
bool visited[NumOfNode];
// the total number of cities   the number of remaining highways    the number of cities to be cheaked
int N, M, K;

void dfs(int node) {
    visited[node] = true;
    for (int i = 1;i <= N;i++) {
        // 未访问过 且 存在边
        if (!visited[i] && edge[node][i] == 1)
            dfs(i);
    }
}

int main () {
    scanf("%d%d%d", &N, &M, &K);
    // 初始化边
    for (int i = 0;i < M;i++) {
        int c1, c2;
        scanf("%d%d", &c1, &c2);
        edge[c1][c2] = edge[c2][c1] = 1;
    }

    int city;
    int res;
    for (int i = 0;i < K;i++) {
        // 对于每个节点而言 所以每次重置 res
        res = 0;
        // 同时重置 visited 数组
        fill(visited, visited + NumOfNode-1, false);
        scanf("%d", &city);
        visited[city] = true;
        // 此处的原理是 如果该区域连通 则通过dfs必能完全搜索,否则的话dfs只能搜索完该区域
        // n 个独立区域 都需要 n - 1 条公路来把他们连通
        for (int j = 1;j <= N;j++) {
            if (!visited[j]) {
                dfs(j);
                // 独立区域+1
                res++;
            }
        }
        printf("%d\n", res-1);
    }
    return 0;
}

题目链接

1013 Battle Over Cities (25分)

参考文章

C++ 中 fill() 的使用
【PAT】1013. Battle Over Cities (25)

你可能感兴趣的:(PAT,算法,dfs,数据结构)