• [题解]lgP5214


    原题链

    思路:由于操作数很小,所以其实大部分的点是不会被修改的,所以预处理出那些永远不会被修改的点,放到并查集里,接着就可以暴力了.

    #include<bits/stdc++.h>
    using namespace std;
    int exist[5010][5010],x[1000010],y[1000010],n,q,m;
    bool vis[5010];
    char ch[1000010];
    int fa[1000010],l[1000010],r[1000010];
    struct node{
    	int next,to;
    }e[1000010 * 2];
    int tot,fir[1000010];
    void add(int x,int to){
    	e[++tot].to=to;
    	e[tot].next=fir[x];
    	fir[x]=tot;
    }
    void dfs(int x){
    	vis[x] = 1;
    	for (int i = fir[x];i;i = e[i].next)
    		if (!vis[e[i].to] && exist[x][e[i].to])
    			dfs(e[i].to);
    }
    int get(int k){
    	if(fa[k] == k)return k;
    	return fa[k] = get(fa[k]);
    }
    int main(){
    	cin>>n>>m;
    	for(int i = 1;i <= m;i++){
    		cin>>x[i]>>y[i];
    		exist[x[i]][y[i]] = exist[y[i]][x[i]] = 1;
    	}
    	for(int i = 1;i <= n;i++)fa[i]=i;
    	cin>>q;
    	for(int i = 1;i <= q;i++){
    		cin>>ch[i];
    		if(ch[i] != 'Q'){
    			cin>>l[i]>>r[i];
    		}
    		if(ch[i] == 'D')
    			exist[l[i]][r[i]] = exist[r[i]][l[i]] = 0;
    	}//不在这里处理ch[i]==A的情况因为这会影响到后面的询问,就是Q1早于某一条连边,但是这条连边由于没有被断开,所以Q1的查询其实是错误的
    //但是可以处理ch[i]==D的情况,因为我们要找的是从来没被修改过的边,而需要修改的可以暴力
    	for(int i = 1;i <= n;i++)
    		for(int j = 1;j <= n;j++)
    			if(exist[i][j])
    				fa[get(i)]=get(j);
    	memset(exist,0,sizeof(exist));
    	for(int i = 1;i <= m;i++){//将原有的边(缩完点之后)相连
    		if(!exist[get(x[i])][get(y[i])]){
    			add(get(x[i]),get(y[i]));
    			add(get(y[i]),get(x[i]));
    		}
    		exist[get(x[i])][get(y[i])]++;
    		exist[get(y[i])][get(x[i])]++;
    	}
    	for(int i = 1;i <= q;i++){
    		if (ch[i]=='Q'){//暴力找联通块
    			memset(vis,0,sizeof(vis));
    			int ans=0;
    			for(int i = 1;i <= n;i++)
    				if(!vis[get(i)])
    					dfs(get(i)),ans++;
    			printf("%d
    ",ans);
    		}
    		if(ch[i] == 'D'){
    			exist[get(l[i])][get(r[i])] = max(0,exist[get(l[i])][get(r[i])] - 1);
    			exist[get(r[i])][get(l[i])] = exist[get(l[i])][get(r[i])];
    		}
    		if(ch[i] == 'A'){
    			if(!exist[get(l[i])][get(r[i])])//没被加入就加边
    				add(get(l[i]),get(r[i])),add(get(r[i]),get(l[i]));
    			exist[get(l[i])][get(r[i])]++;
    			exist[get(r[i])][get(l[i])]++;
    		}
    	}
    	return 0;
    }
    

    参考题解

  • 相关阅读:
    面试小结
    Everything工具使用
    记 · 工作一周年
    贝叶斯算法原理分析
    MySQL与Oracle主键Query性能测试结果
    K-meams文本聚类算法C++实现
    OPTICS光学算法
    页面添加内容后弹出框与跳转页面
    Webgrid参数格式
    页面2级分类
  • 原文地址:https://www.cnblogs.com/czy--blog/p/13844382.html
Copyright © 2020-2023  润新知