pta--1013 Battle Over Cities (25)(dfs或并查集)

It is vitally important to have all the cities connected by highways in a war. If a city is occupied by the enemy, all the highways from/toward that city are closed. We must know immediately if we need to repair any other highways to keep the rest of the cities connected. Given the map of cities which have all the remaining highways marked, you are supposed to tell the number of highways need to be repaired, quickly.

For example, if we have 3 cities and 2 highways connecting city~1~-city~2~ and city~1~-city~3~. Then if city~1~ is occupied by the enemy, we must have 1 highway repaired, that is the highway city~2~-city~3~.

Input

Each input file contains one test case. Each case starts with a line containing 3 numbers N (&lt1000), M and K, which are the total number of cities, the number of remaining highways, and the number of cities to be checked, respectively. Then M lines follow, each describes a highway by 2 integers, which are the numbers of the cities the highway connects. The cities are numbered from 1 to N. Finally there is a line containing K numbers, which represent the cities we concern.

Output

For each of the K cities, output in a line the number of highways need to be repaired if that city is lost.

Sample Input

3 2 3
1 2
1 3
1 2 3

Sample Output

1
0
0

 题意:给出几个城市以及哪几个城市间连通,计算某个城市被攻陷后最少要修几条路使得各个城市连通。其实就是求连通分量吧;个数就是连通分量-1;

【dfs】

#include<bits/stdc++.h>
using namespace std;
int n;//城市数
int v[1005][1005]; 
int visit[1005];
int dfs(int node)
{
	visit[node]=1;
	for(int i=1;i<=n;i++)
		if(!visit[i]&&v[node][i])dfs(i);
}
int main()
{
	int m,k,a,b;
	scanf("%d%d%d",&n,&m,&k);
	for(int i=0;i<m;i++)
	{
		scanf("%d%d",&a,&b);
		v[a][b]=1;v[b][a]=1;
	}
	for(int i=1;i<=k;i++)
	{
		fill(visit,visit+1005,0);
		int t,cnt=0;
		scanf("%d",&t);
		visit[t]=1;
		for(int j=1;j<=n;j++)
		{
			if(!visit[j])
				dfs(j),cnt++;
		}
		cout<<cnt-1<<endl;
	}
	return 0;
}

【并查集】代码:https://blog.csdn.net/tuzigg123/article/details/46969995

#include <iostream>
#include <vector>
using namespace std;
//并查集
int findroot(vector<int> &root,int a){
	if(root[a]!=a)
		root[a]=findroot(root,root[a]);//路径压缩,本结点更新为根结点的子结点
	return root[a];
}
 
int graphNum(const vector<pair<int,int> > &roads,int N,int lostCityNum){
	vector<int> root;
	for(int i=0;i<=N;i++)
		root.push_back(i);//一开始每个结点的根结点都是自身
	int result=N-1;//失去一个城市后,最多有N-1个子图
	for(auto it=roads.begin();it!=roads.end();it++){
		if((*it).first!=lostCityNum&&(*it).second!=lostCityNum){
			int ar=findroot(root,(*it).first);
			int br=findroot(root,(*it).second);
			if(ar!=br){
				result--;
				root[ar]=br;
			}
		}
	}
	return result;
}
int main(){
	int N,M,K;
	cin>>N>>M>>K;
	vector<pair<int,int> > roads;
	int a,b;
	while(M--){
		cin>>a>>b;
		roads.push_back(make_pair(a,b));
	}
	int x;
	while(K--){
		cin>>x;
		cout<<graphNum(roads,N,x)-1<<endl;//子图数减1
	}
	return 0;
}

【pair模板】

 pair模板类用来绑定两个对象为一个新的对象,该类型在<utility>头文件中定义。该模板类支持一下操作:

  • pair<T1,T2>p1:创建一个空的pair对象,它的两个元素分别是T1和T2类型,采用值初始化;

  • pair<T1,T2>p1<v1,v2>:创建一个pair对象,它的两个元素分别是T1和T2类型,first成员初始化为v1,second成员初始化为v2;

  • make_pair(v1,v2):以v1、v2值创建一个新的pair对象,其元素类型分别是v1和v2的类型。

  • p.first  返回p中名为first的(公有)数据成员

  • p.second   返回p中名为second的(公有)数据成员

  • p1 < p2字典次序   如果p1.first<p2.first或者!(p2.first <p1.first)&& p1.second<p2.second,则返回true

  • p1 == p2     如果两个pair对象的first和second成员依次相等,则这两个对象相等。

pair可以将两个值视为一个单元,C++ STL中多处使用了这个类。尤其容器类map,multimap,就是使用pairs来管理其键/值(key/value)的成对元素。任何函数想返回2个的值都可以使用pair

猜你喜欢

转载自blog.csdn.net/qq_38735931/article/details/81742145