zoukankan      html  css  js  c++  java
  • [PAT] A1013 Battle Over Cities (25分)

    题目大意

    给出n个城市之间有相互连接的m条道路,当删除一个城市和其连接的道路的时候,问其他几个剩余的城市至少要添加多少个路线才能让它们重新变为连通图。

    思路

    添加的最少的路线,就是他们的连通分量数-1,因为当a个互相分立的连通分量需要变为连通图的时候,只需要添加a-1个路线,就能让他们相连。所以这道题就是求去除了某个结点之后其他的图所拥有的连通分量数。
    使用邻接表存储(也可以用邻接矩阵),对于每一个被占领的城市,去除这个城市结点,就是把它标记为已经访问过,这样在遍历的时候,对于所有未访问的结点进行遍历,就会跳过那个城市,最终求出所有的连通分量的个数。
    注意:因为有很多个要判断的数据,每一次输入被占领的城市之前要把visit数组置为false。

    AC代码

    用了深度优先遍历和广度优先遍历来写,除了遍历核心代码(即函数DFS(int x)和BFS(int x))之外其余代码都完全相同。深度优先遍历写起来更方便些。

    DFS

    #define _CRT_SECURE_NO_WARNINGS
    #include<iostream>
    #include<vector>
    using namespace std;
    #define MAX 1002
    vector<int>Adj[MAX];
    bool vis[MAX] = { false };
    int M, N, K;
    void DFS(int x) {
    	vis[x] = true;
    	for (int i = 0; i < Adj[x].size(); i++)
    		if (vis[Adj[x][i]] == false)
    			DFS(Adj[x][i]);
    }
    int Trave(int s) {
    	int i, times = 0;
    	fill(vis, vis + N + 1, false);
    	vis[s] = true;
    	for (i = 1; i <= N; i++) {
    		if (vis[i] == false) {
    			DFS(i);
    			times++;
    		}
    	}
    	return times;
    }
    int main() {
    	int i, temp, a, b;
    	scanf("%d%d%d", &N, &M, &K);
    	for (i = 0; i < M; i++) {
    		scanf("%d%d", &a, &b);
    		Adj[a].push_back(b);
    		Adj[b].push_back(a);
    	}
    	for (i = 0; i < K; i++) {
    		scanf("%d", &temp);
    		printf("%d
    ", Trave(temp) - 1);
    	}
    	return 0;
    }
    

    BFS

    #define _CRT_SECURE_NO_WARNINGS
    #include<iostream>
    #include<queue>
    #include<vector>
    using namespace std;
    #define MAX 1002
    #define INF 10000000
    vector<int>Adj[MAX];
    bool vis[MAX] = { false };
    int M, N, K;
    int BFS(int x) {
    	int ans = 1;
    	queue<int>q;
    	q.push(x);
    	vis[x] = true;
    	while (!q.empty()) {
    		int t = q.front();
    		for (int i = 0; i < Adj[t].size(); i++) {
    			int v = Adj[t][i];
    			if (vis[v] == false) {
    				q.push(v);
    				vis[v] = true;
    			}
    		}
    		q.pop();
    	}
    	return ans;
    }
    int Trave(int s) {
    	int i, times = 0;
    	fill(vis, vis + N + 1, false);
    	vis[s] = true;
    	for (i = 1; i <= N; i++) {
    		if (vis[i] == false) {
    			BFS(i);
    			times++;
    		}
    	}
    	return times;
    }
    int main() {
    	int i, temp, a, b;
    	scanf("%d%d%d", &N, &M, &K);
    	for (i = 0; i < M; i++) {
    		scanf("%d%d", &a, &b);
    		Adj[a].push_back(b);
    		Adj[b].push_back(a);
    	}
    	for (i = 0; i < K; i++) {
    		scanf("%d", &temp);
    		printf("%d
    ", Trave(temp) - 1);
    	}
    	return 0;
    }
    
  • 相关阅读:
    定时任务(收集)
    命令学习(收集)
    查看进程运行时间
    Linux 中挂载 ISO 文件
    9.已知三边计算三角形的面积公式
    8.输入一个大写字母,要求小写字母输出
    1.输出三个数中的最大值
    2.依次从大到小输出三个数
    3.计算1+2+3+....100=?
    4.计算1*2*3*4........*100=?
  • 原文地址:https://www.cnblogs.com/yue36/p/13600670.html
Copyright © 2011-2022 走看看