zoukankan      html  css  js  c++  java
  • 洛谷 P1197 [JSOI2008]星球大战(并查集,建图)

    传送门


    解题思路

    每次删边复杂度太高,所以可以倒序加边。
    注意在对方占领后,这个点就不参与连通块数量的计算了。

    AC代码

    	#include<iostream>
    	#include<cstdio>
    	#include<cstring>
    	#include<cmath>
    	#include<algorithm>
    	using namespace std;
    	const int maxn=4e5+5;
    	int n,m,k,a[maxn],p[maxn],cnt,num,fa[maxn],ans[maxn],q[maxn],vis[maxn];
    	struct node{
    		int v,next;
    	}e[maxn];
    	void insert(int u,int v){
    		num++;
    		e[num].v=v;
    		e[num].next=p[u];
    		p[u]=num;
    	}
    	int find(int x){ return fa[x]=(fa[x]==x?x:find(fa[x]));}
    	int main(){
    		ios::sync_with_stdio(false);
    		memset(p,-1,sizeof(p));
    		cin>>n>>m;
    		for(int i=1;i<=n;i++){
    			fa[i]=i;
    		}
    		for(int i=1;i<=m;i++){
    			int u,v;
    			cin>>u>>v;
    			insert(u,v);
    			insert(v,u);
    		}
    		cin>>k;
    		for(int i=1;i<=k;i++){
    			cin>>q[i];
    			vis[q[i]]=1;
    		}
    		for(int u=0;u<n;u++){
    			if(!vis[u]){
    				for(int i=p[u];i!=-1;i=e[i].next){
    					int v=e[i].v;
    					if(vis[v]) continue;
    					int f1=find(u),f2=find(v);
    					if(f1!=f2){
    						fa[f1]=f2;
    						cnt++;
    					}
    				}
    			}
    		}
    		ans[k]=n-k-cnt;
    		for(int u=k;u>=1;u--){
    			vis[q[u]]=0;
    			for(int i=p[q[u]];i!=-1;i=e[i].next){
    				int v=e[i].v;
    				if(vis[v]) continue;
    				int f1=find(q[u]),f2=find(v);
    				if(f1!=f2){
    					fa[f1]=f2;
    					cnt++;
    				}
    			}
    			ans[u-1]=n-(u-1)-cnt;
    		}
    		for(int i=0;i<=k;i++) cout<<ans[i]<<endl;
    		return 0;
    	}
    
  • 相关阅读:
    面试题:能谈谈Date、Datetime、Time、Timestamp、year的区别吗?
    面试题:对NotNull字段插入Null值 有啥现象?
    聊聊什么是慢查、如何监控?如何排查?
    谈谈MySQL的基数统计
    .vimrc
    HISKrrr的板子库
    CSP 模拟35
    晚测1
    CSP 模拟34
    nim板子题异或正确性YY
  • 原文地址:https://www.cnblogs.com/yinyuqin/p/15292680.html
Copyright © 2011-2022 走看看