1013 Battle Over Cities(图的DFS解法)

Posted CSU迦叶

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了1013 Battle Over Cities(图的DFS解法)相关的知识,希望对你有一定的参考价值。

 这题的背景是战争年代,假如城市1被占领,那么所有和城市1相关的公路都要被炸毁,但是这样一来,2和3就不连通了,所以需要补修一条23之间的公路。但是换做城市2或3被占领,1和另一座城市是联通的,并不需要补修公路。

因此这题是求删去一个结点后,剩下的图中的连通子图的数量,再减去1就是最终要求的结果了。

两个犯傻的地方:

1. 我用DFS和邻接表做这题,还开了两个邻接表,一个用于保存和恢复,增加了不少代码量,其实无需真正去“炸毁公路(删除边)”,只要遍历到被占领的城市跳过即可。

2. 由于DFS需要维护一个哈希数组,并在每次遍历前恢复零,但是注意这里城市的编号从1开始,所以调用fill函数的话,一定是下面这样

fill(vis,vis+allCityNum+1,0);//加一必不可少 

第二个参数是数组名+城市的数目+1!!

关于DFS的写法:

之前想着删边的时候,有两类边要删除,假设被占领城市的编号是lostIdx,那么G[lostIdx]所在的向量要整个clear(),其他的i≠lostIdx的G[i]里面如果存在lostIdx也要删除。这两个分别对应dfsTrave()和dfs(int idx)里面的判断

void dfsTrave(){
	for(int j=1;j<=allCityNum;j++){
		if(j!=lostIdx&&vis[j]==0){
			dfs(j);
			needNum ++;
		}
	}
}

void dfs(int idx){
	if(idx==lostIdx)return;
	else{
		vis[idx] = 1;
		for(int i=0;i<G[idx].size();i++){
			int u = G[idx][i];
			if(vis[u]==0)dfs(u);
		}
	}
	
}

此外:

我是把需要炸毁的城市数目记作-1,进行一次dfs就加一,所以需要判断一开始是不是只有一座城市,不然会输出-1来。

AC代码

#include<cstdio>
#include<map>
#include<set>
#include<string>
#include<cstring>
#include<iostream>
#include<vector>
#include<stack>
#include<queue>
#include<algorithm>
#include<cmath>
typedef long long LL;

using namespace std;

const int maxn = 1010;//总城市数上限 

vector<int> G[maxn];

int allCityNum,lostIdx;

int needNum = -1;
bool vis[maxn] = {0};

void dfs(int idx){
	if(idx==lostIdx)return;
	else{
		vis[idx] = 1;
		for(int i=0;i<G[idx].size();i++){
			int u = G[idx][i];
			if(vis[u]==0)dfs(u);
		}
	}
	
}

void dfsTrave(){
	for(int j=1;j<=allCityNum;j++){
		if(j!=lostIdx&&vis[j]==0){
			dfs(j);
			needNum ++;
		}
	}
}


int main(){

	int wayNum,lostCityNum;
	scanf("%d %d %d",&allCityNum,&wayNum,&lostCityNum);
	
	for(int i=0;i<wayNum;i++){
		int ct1,ct2;
		scanf("%d %d",&ct1,&ct2);
		G[ct1].push_back(ct2);
		G[ct2].push_back(ct1);
	}
	
	
	
	for(int i=0;i<lostCityNum;i++){
		scanf("%d",&lostIdx);
		
		if(allCityNum == 1){
			printf("0\\n");
		}else{ 

			//关键操作
			needNum = -1; 
			fill(vis,vis+allCityNum+1,0);//加一必不可少 
			dfsTrave();
			printf("%d\\n",needNum);
			
		}
	}
	
	
	return 0;
}

以上是关于1013 Battle Over Cities(图的DFS解法)的主要内容,如果未能解决你的问题,请参考以下文章

PAT 甲级测试题目 -- 1013 Battle Over Cities

1013. Battle Over Cities (25)

PAT 1013 Battle Over Cities

PAT 1013. Battle Over Cities

PAT1013: Battle Over Cities

1013 Battle Over Cities