zoukankan      html  css  js  c++  java
  • BZOJ 3563 DZY Loves Chinese

    题解:为每条非树边赋一个权值

    每条树边的权值为覆盖他的非树边权值异或和

    如果边集的子集线性相关,相当于把树边和非树边拦腰砍断,则不连通

    用线性基判断线性相关

    问题:为什么srand(time(0))会RE?

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<ctime>
    #include<cstdlib>
    using namespace std;
    const int maxn=1000009;
    
    int n,m,T;
    
    int rx[maxn],ry[maxn],vis[maxn],rd[maxn];
    
    int ufsfa[maxn];
    int Getf(int x){
    	if(ufsfa[x]==x)return x;
    	return ufsfa[x]=Getf(ufsfa[x]);
    }
    void Unionn(int x,int y){
    	int fx=Getf(x);
    	int fy=Getf(y);
    	if(fx!=fy)ufsfa[fx]=fy;
    }
    
    int cntedge;
    int head[maxn];
    int to[maxn],nex[maxn],num[maxn];
    void Addedge(int x,int y,int ide){
    	nex[++cntedge]=head[x];
    	to[cntedge]=y;
    	num[cntedge]=ide;
    	head[x]=cntedge;
    }
    
    int father[maxn];
    int dep[maxn];
    int fatheredge[maxn];
    int Dfs(int now,int fa){
    	father[now]=fa;
    	dep[now]=dep[fa]+1;
    	for(int i=head[now];i;i=nex[i]){
    		if(to[i]==fa)continue;
    		fatheredge[to[i]]=num[i];
    		Dfs(to[i],now);
    	}
    }
    
    int mar[maxn];
    void Dp(int x,int fa){
    	for(int i=head[x];i;i=nex[i]){
    		if(to[i]==fa)continue;
    		Dp(to[i],x);
    		mar[x]^=mar[to[i]];
    	}
    }
    
    int lastans;
    int a[maxn];
    
    int c[100];
    int isOK(int n){
    	memset(c,0,sizeof(c));
    	for(int i=1;i<=n;++i){
    		int x=rd[a[i]];
    		for(int j=30;j>=1;--j){
    			if(x&(1<<(j-1))){
    				if(c[j]==0){
    					c[j]=x;
    					break;
    				}else{
    					x^=c[j];
    				}
    			}
    		}
    		if(x==0)return 0;
    	}
    //	for(int i=30;i>=1;--i)printf("%d ",c[i]);
    //	cout<<endl;
    	return 1;
    }
    
    void Minit(){
    	lastans=0;
    	memset(mar,0,sizeof(mar));
    	dep[0]=0;
    	memset(head,0,sizeof(head));
    	memset(vis,0,sizeof(vis));
    	cntedge=0;
    }
    
    int main(){
    //	int fuck=time(0);
    	srand(19260917);
    	scanf("%d%d",&n,&m);
    	Minit();
    	
    	for(int i=1;i<=n;++i)ufsfa[i]=i;
    	for(int i=1;i<=m;++i){
    		scanf("%d%d",&rx[i],&ry[i]);
    		if(Getf(rx[i])!=Getf(ry[i])){
    			Unionn(rx[i],ry[i]);
    			vis[i]=1;
    			Addedge(rx[i],ry[i],i);
    			Addedge(ry[i],rx[i],i);
    		}
    	}
    	Dfs(1,0);
    	for(int i=1;i<=m;++i){
    		if(vis[i])continue;
    		if(dep[rx[i]]>dep[ry[i]])swap(rx[i],ry[i]);
    		int dist=(int)(1LL*rand()*rand()%1000000000+1);
    //		cout<<dist<<endl;
    		rd[i]=dist;
    		mar[ry[i]]^=dist;
    		mar[rx[i]]^=dist;
    	}
    	Dp(1,0);
    	for(int i=2;i<=n;++i){
    		rd[fatheredge[i]]=mar[i];
    	}
    //	for(int i=1;i<=m;++i)printf("%d ",rd[i]);
    //	cout<<endl;
    	scanf("%d",&T);
    	while(T--){
    		int k;
    		scanf("%d",&k);k^=lastans;
    		for(int i=1;i<=k;++i)scanf("%d",&a[i]);
    		for(int i=1;i<=k;++i)a[i]^=lastans;
    		
    		if(isOK(k))++lastans,printf("Connected
    ");
    		else printf("Disconnected
    ");
    	}
    	return 0;
    }
    

      

    自己还是太辣鸡了
  • 相关阅读:
    SQL注入过滤
    ASP.NET长文章分页
    简单的权限管理类
    不错的面试题
    【转载】【重要】Ubuntu Linux 下 Ffmpeg 及 Mencoder 安装使用小结
    回到xwindows
    suse11 linux不自动启动xwindows
    flash的几种工具
    mencoder和ffmpeg参数详解
    ffmpeg和Mencoder使用实例小全
  • 原文地址:https://www.cnblogs.com/zzyer/p/8454421.html
Copyright © 2011-2022 走看看