您的位置:首页 > 其它

bzoj3569: DZY Loves Chinese II【线性基】

2018-01-05 22:20 330 查看

解题思路:

这是一道套路题.

先 DFS 出一个生成树, 对于非树边随机一 权值, 树边的权值为覆盖它的非树边的权值异或和,这个可以2遍dfs处理。

然后删掉指定的 k 条边后原图不连通当且仅当这些边的权值存在一个异或和为 0 的子集。


4000
后求线性无关组,看是否有一条边的权值是非线性基即可。

#include<bits/stdc++.h>
#define ll unsigned long long
using namespace std;

int getint()
{
int i=0,f=1;char c;
for(c=getchar();(c!='-')&&(c<'0'||c>'9');c=getchar());
if(c=='-')c=getchar(),f=-1;
for(;c>='0'&&c<='9';c=getchar())i=(i<<3)+(i<<1)+c-'0';
return i*f;
}

const int N=100005,M=1000005,S=1e9;
int Q,n,m,ans;
int tot=1,first
,nxt[M],to[M],w[M];
int val
,base[35];
bool vis
,use[M];

void add(int x,int y)
{
nxt[++tot]=first[x],first[x]=tot,to[tot]=y;
}

void dfs1(int u)
{
vis[u]=1;
for(int e=first[u];e;e=nxt[e])
{
int v=to[e];
if(vis[v])continue;
use[e>>1]=1;
dfs1(v);
}
}

void dfs2(int u)
{
vis[u]=1;
for(int e=first[u];e;e=nxt[e])
{
int v=to[e];
if(vis[v])continue;
dfs2(v);
w[e>>1]^=val[v];
val[u]^=val[v];
}
}

int main()
{
//freopen("lx.in","r",stdin);
int x,y;
srand(1);
n=getint(),m=getint();
for(int i=1;i<=m;i++)
{
x=getint(),y=getint();
add(x,y),add(y,x);
}
dfs1(1);
for(int e=2;e<=tot;e++)
if(!use[e>>1])
{
x=rand()%S+1,use[e>>1]=1;
w[e>>1]=x,val[to[e]]^=x,val[to[e^1]]^=x;
}
memset(vis,0,sizeof(vis));
dfs2(1);
Q=getint();
while(Q--)
{
int bz=0;m=getint();
memset(base,0,sizeof(base));
for(int i=1;i<=m;i++)
{
x=w[getint()^ans];
for(int j=30;j>=0;j--)
if(x&(1<<j))
{
if(base[j])x^=base[j];
else{base[j]=x;break;}
}
if(!x)bz=1;
}
bz?puts("Disconnected"):(puts("Connected"),ans++);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: