1 条题解

  • 1
    @ 2021-12-29 21:06:30

    考虑异或和的二进制下的一的个数有什么性质。

    f(x)f(x) 表示 xx 二进制下一的个数的奇偶性,那么会发现一个有趣的性质。

    f(xy)=f(x)f(y)f(x \oplus y)=f(x) \oplus f(y)

    我们发现这个东西满足异或的性质,所以设 g(i,j)g(i,j) 表示 iijj 链上的异或和的一的个数奇偶性。

    那么可以得到 g(x,y)=g(1,x)g(1,y)g(x,y)=g(1,x) \oplus g(1,y)

    然后可以发现 g(1,x)g(1,x) 要么是 11 ,要么是 00,约束条件实际上约束了 g(1,x)g(1,x)g(1,y)g(1,y)

    直接扩展域并查集就好了。


    代码
    #include<bits/stdc++.h>
    using namespace std;
    const int N=2e5+5;
    int _,n,m;
    vector<pair<int,int> > e[N];
    int f[N<<1],fff;
    struct Ans{int x,y,s;}ans[N];
    int getanc(int k){return f[k]==k?k:f[k]=getanc(f[k]);}
    void he(int x,int y){if(getanc(x)!=getanc(y))f[getanc(x)]=y;}//合并
    bool work(int x){
    	bool s=1;
    	for(;x;x>>=1)if(x&1)s=!s;
    	return s;
    }
    void dfs(int x,int fa){
    	for(auto i:e[x]){
    		int y=i.first,z=i.second;
    		if(y==fa)continue;
    		if(z!=-1){
    			if(work(z))he(x,y),he(x+n,y+n);
    			else he(x,y+n),he(x+n,y);
    		}
    		dfs(y,x);
    	}
    }
    int main(){
    	scanf("%d",&_);
    	while(_--){
    		int ff=0;
    		scanf("%d%d",&n,&m);
    		for(int i=1;i<=n;i++)e[i].clear();
    		for(int i=1;i<=2*n;i++)f[i]=i;
    		for(int i=1,x,y,z;i<n;i++){
    			scanf("%d%d%d",&x,&y,&z);
    			e[x].emplace_back(y,z);
    			e[y].emplace_back(x,z);
    			ans[i]=(Ans){x,y,z};
    		}
    		dfs(1,0);
    		for(int i=1,x,y,p;i<=m;i++){
    			scanf("%d%d%d",&x,&y,&p);
    			if(p==1){
    				if(getanc(x)==getanc(y)||getanc(x+n)==getanc(y+n))ff=1;
    				he(x,y+n),he(y,x+n);
    			}
    			else{
    				if(getanc(x)==getanc(y+n)||getanc(x+n)==getanc(y))ff=1;
    				he(x,y),he(y+n,x+n);
    			}
    		}
    		if(ff)puts("NO");
    		else{
    			puts("YES");
    			for(int i=1;i<n;i++){
    				if(ans[i].s==-1){
    					if(getanc(ans[i].x)==getanc(ans[i].y)||getanc(ans[i].x+n)==getanc(ans[i].y+n))ans[i].s=0;
    					else{
    						ans[i].s=1;
    						he(ans[i].x,ans[i].y+n);
    						he(ans[i].x+n,ans[i].y);
    					} 
    				}
    				printf("%d %d %d\n",ans[i].x,ans[i].y,ans[i].s);
    			}
    		}
    	}
    }
    
    • 1

    信息

    ID
    63
    时间
    2000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者