0
点赞
收藏
分享

微信扫一扫

L2-013 红色警报(并查集判断联通分量数)

九点韶留学 2022-03-14 阅读 17
  • 题目链接:L2-013 红色警报
  • 考查知识:并查集判断联通分量数
  • 题意描述:给定n个城市m条道路,然后判断删除给定结点后无向图联通分量的变化情况
  • 思路简析:题意的“整个国家的连通性”,易知最少原联通分量1分为2,然后还有我们删的一个城市,所以用cn2-cn>1判断
  • 具体代码
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N=5e2+10; 
    int fa[N],e[N][N];
    void init(int n){
    	for(int i=0;i<n;i++)//[0,n) 
    		fa[i]=i;
    } 
    int find(int x){
    	if(x==fa[x])return x;
    	else return fa[x]=find(fa[x]);
    }
    void merge(int a,int b){
    	int faA=find(a),faB=find(b);
    	if(faA!=faB)fa[faA]=faB;
    }
    int main(){
    	int n,m,k;
    	cin>>n>>m;//n个城市m条道路 
    	init(n);//find 开始之前要初始化
    	int a,b;
    	for(int i=0;i<m;i++){
    		cin>>a>>b;
    		e[a][b]=e[b][a]=1;
    		merge(a,b);
    	}
    	int cn=0;//记录初始连通块的个数
    	for(int i=0;i<n;i++){
    		if(i==find(i))cn++;
    	}
    	cin>>k;
    	for(int i=0;i<k;i++){
    		cin>>a;
    		for(int i=0;i<n;i++){
    			e[a][i]=e[i][a]=0;//t1城市的路径消失 
    		}
    		init(n);//find 开始之前要初始化
    		for(int i=0;i<n;i++){//重新建立并查集 
    			for(int j=0;j<n;j++){
    				if(e[i][j])merge(i,j);
    			}
    		}
    		int cn2=0;//记录结束连通块的个数
    		for(int i=0;i<n;i++){
    			if(i==find(i))cn2++;
    		}
    		if(cn2-cn>1)cout<<"Red Alert: City "<<a<<" is lost!"<<endl;
    		else cout<<"City "<<a<<" is lost."<<endl;
    		cn=cn2;//更新 连通分量
    	}
    	if(k==n)cout<<"Game Over."<<endl;//攻占全部城市则游戏结束 
    	return 0;
    }
    
    
举报

相关推荐

0 条评论