zoukankan      html  css  js  c++  java
  • [51Nod1515]明辨是非

    [51Nod1515]明辨是非

    题目大意:

    (n(nle10^5))组操作,每组操作形式为x y p

    (p)(1)时,如果第(x)变量和第(y)个变量可以相等,则输出YES,并限制他们相等;否则输出NO,并忽略此次操作。

    (p)(0)时,如果第(x)变量和第(y)个变量可以不相等,则输出YES,并限制他们不相等 ;否则输出NO,并忽略此次操作。

    思路:

    注意不等号不具有传递性,因此[NOI2015]程序自动分析的做法并不适用于这一题。

    并查集维护相同的数,set里面存不相同的数。按秩和并即可。

    源代码:

    #include<set>
    #include<cstdio>
    #include<cctype>
    #include<numeric>
    #include<algorithm>
    inline int getint() {
    	register char ch;
    	while(!isdigit(ch=getchar()));
    	register int x=ch^'0';
    	while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
    	return x;
    }
    const int M=1e5,N=2e5+1;
    struct Modify {
    	int x,y,p;
    };
    Modify q[M];
    int tmp[N];
    std::set<int> set[N];
    struct DisjointSet {
    	int anc[N];
    	int find(const int &x) {
    		return x==anc[x]?x:anc[x]=find(anc[x]);
    	}
    	void reset(const int &n) {
    		std::iota(&anc[1],&anc[n]+1,1);
    	}
    	void merge(int x,int y) {
    		if(set[x].size()<set[y].size()) {
    			std::swap(x,y);
    		}
    		anc[y]=x;
    		for(auto p:set[y]) {
    			const int z=find(p);
    			set[p].erase(y);
    			set[x].insert(z);
    			set[z].insert(x);
    		}
    		set[y].clear();
    	}
    	bool same(const int &x,const int &y) {
    		return find(x)==find(y);
    	}
    };
    DisjointSet djs;
    int main() {
    	const int m=getint();
    	for(register int i=0;i<m;i++) {
    		q[i].x=getint();
    		q[i].y=getint();
    		q[i].p=getint();
    		tmp[++tmp[0]]=q[i].x;
    		tmp[++tmp[0]]=q[i].y;
    	}
    	std::sort(&tmp[1],&tmp[tmp[0]]+1);
    	const int n=std::unique(&tmp[1],&tmp[tmp[0]]+1)-&tmp[1];
    	djs.reset(n);
    	for(register int i=0;i<m;i++) {
    		int x=djs.find(std::lower_bound(&tmp[1],&tmp[n]+1,q[i].x)-tmp);
    		int y=djs.find(std::lower_bound(&tmp[1],&tmp[n]+1,q[i].y)-tmp);
    		if(q[i].p) {
    			if(!set[x].count(y)) {
    				puts("YES");
    				if(x!=y) djs.merge(x,y);
    			} else {
    				puts("NO");
    			}
    		} else {
    			if(!djs.same(x,y)) {
    				puts("YES");
    				set[x].insert(y);
    				set[y].insert(x);
    			} else {
    				puts("NO");
    			}
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    Oracle 左连接、右连接、全外连接、(+)号作用
    ORA-01940:无法删除当前已链接的用户(转)
    博客正式开通
    python扫描内网存活主机(scapy与nmap模块)
    Python学习之扫描网段主机与开启端口(避坑)
    Python学习之服务器与客户端的交互
    python渗透测试编程之kali linux2的AptanaStudio3安装
    Shellcodeloader免杀过火绒
    Cracer之Waf绕过
    30 Day Challenge Day 16 | Leetcode 692. Top K Frequent Words
  • 原文地址:https://www.cnblogs.com/skylee03/p/9705666.html
Copyright © 2011-2022 走看看