PAT.A1013 Battle Over Cities

Back to ContentsInsert picture description here

Title

Given an undirected graph and stipulate that when deleting a vertex in the graph, the edges connected to it will be deleted at the same time. Next, k queries are given, each query is given a vertex number to be deleted, and how many edges need to be added after deleting the vertex (and the edges connected to it) to make the graph become connected (Note: k queries All on the original picture).

Sample (can be copied)

3 2 3
1 2
1 3
1 2 3
//output
1
0
0

important point

  1. This question provides and investigates two methods of collecting and DFS
  2. And check the method: because the number of edges to be added is equal to the number of connected blocks minus 1, it is enough to find how many blocks the root node block, the answer is block-1. In this question, the path collection must be compressed or it will time out.
  3. The DFS method starts from node 1 from small to large, and marks the visited nodes as flags. After that, only the non-deleted nodes and nodes that have not been visited are accessed, and the block is incremented by 1 for each access.

And check

#include<bits/stdc++.h>
using namespace std;

const int N=1010;
vector<int> G[N];//图 
bool flag[N];//标记是否访问过 
int root[N];//root[i]=x存放每个节点i对应的根节点x
int n,m,k,del;
int findroot(int a){
	int b=a;
	while(a!=root[a])a=root[a];
	while(b!=root[b]){//缩短节点到根节点的距离
		int t=b;
		b=root[b];
		root[t]=a;
	}
	return a;
}
void Union(int a,int b){
	int aa=findroot(a),bb=findroot(b);
	if(aa!=bb)root[aa]=bb;
}
void init(){
	for(int i=1;i<=n;i++)root[i]=i;
	memset(flag,false,sizeof(flag));
}
int main(){
	cin>>n>>m>>k;
	int a,b;
	while(m--){
		scanf("%d %d",&a,&b);
		G[a].push_back(b);
		G[b].push_back(a);
	}
	while(k--){
		scanf("%d",&del);
		init();//每次查询都要重置flag和root 
		for(int i=1;i<=n;i++) {
			for(int j=0;j<G[i].size();j++){
				if(i==del||G[i][j]==del)continue;
				Union(i,G[i][j]);
			}
		}
		int block=0;
		for(int i=1;i<=n;i++){
			if(i==del)continue;
			int rooti=findroot(i);
			if(!flag[rooti]){
				block++;
				flag[rooti]=true;
			}
		}
		printf("%d\n",block-1);
	}
    return 0;
}

DFS

#include<bits/stdc++.h>
using namespace std;

const int N=1010;
vector<int> G[N];//图 
bool flag[N];//标记节点是否访问过
int n,m,k,del;
void DFS(int v){
	if(v==del)return;
	flag[v]=true;
	for(int i=0;i<G[v].size();i++){
		if(!flag[G[v][i]])DFS(G[v][i]);
	}
}
int main(){
	cin>>n>>m>>k;
	int a,b;
	while(m--){//m条边
		scanf("%d %d",&a,&b);
		G[a].push_back(b);
		G[b].push_back(a);
	}
	while(k--){//k次查询
		scanf("%d",&del);
		int block=0;
		memset(flag,false,sizeof(flag));
		for(int i=1;i<=n;i++){
			if(!flag[i]&&i!=del){
				DFS(i);
				block++;
			}
			flag[i]=true;
		}
		printf("%d\n",block-1);
	}
    return 0;
}
Published 177 original articles · won praise 5 · Views 6657

Guess you like

Origin blog.csdn.net/a1920993165/article/details/105531431