この問題は、最初のスパニングツリー・ルーチンを見つけるためには、その後、残りの部分は、いくつかの非ツリーエッジになり、エッジがダイアグラムを削除したくなる接続されていません(最初の非ツリーエッジをカットすることを仮定した場合)の場合と全く先祖返りエッジを削除するには、存在しない場合にのみ、木の側面を覆う、木または削除両側縁は、非ツリーの同じセットによって覆われています
今、この問題に対処するために。我々は、すべての木の非ランダムウエイト側を与え、その後、ツリーの右側の値は、その非ツリーエッジの重みやで覆われている別のこの差は木、異なる場合ツリーの2つの側面を達成することができます木とXOR 0の片側はないと考え覆われている場合は、同じとその非被覆ツリーエッジセットに等しいと思います。私たちのランダムな範囲ならば\(2 ^ \ wは)、エラーの確率があります\(\ FRAC。1 {{}} W ^ 2 \) 、選択された数に対応する数だけがエラーであろう正確ため
。エッジのセットを与える結論排他的論理和の値及びサブ集中0次に誘導証明のエッジ上のフォーカスがある場合にのみ場合、通信は、後で削除されません与えられる場合、非ツリーの全体のサブセットサイドそれは他の場所にあるであろう直接WA;その他の非木の辺に選出された木の側面がある場合はそれで覆われている、それは通信後に削除されることはありません。そこにいる場合(\ GE 2 \)\ツリーの片側が、その後、私たちは非他を置くことができますなお、エッジにそれぞれツリーエッジにXOR木、木は、2つの側面を有しており、同一又は異なるように波をお勧めします合理的証拠が。基は直鎖状であってもよい達成される、サブセットが発生することが関連する線形は通信しません
#include<bits/stdc++.h>
#define LL long long
#define uLL unsigned long long
#define db double
using namespace std;
const int N=1e5+10;
int rd()
{
int x=0,w=1;char ch=0;
while(ch<'0'||ch>'9'){if(ch=='-') w=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
return x*w;
}
int to[N*10],nt[N*10],hd[N],tot=1;
void add(int x,int y)
{
++tot,to[tot]=y,nt[tot]=hd[x],hd[x]=tot;
++tot,to[tot]=x,nt[tot]=hd[y],hd[y]=tot;
}
int n,m,q,fa[N],de[N],sz[N],hs[N],top[N];
uLL a[N],w[N*5],bs[70];
bool vv[N*5];
void dfs1(int x)
{
sz[x]=1;
for(int i=hd[x];i;i=nt[i])
{
int y=to[i];
if(de[y]) continue;
vv[i>>1]=1;
fa[y]=x,de[y]=de[x]+1,dfs1(y);
sz[x]+=sz[y],hs[x]=sz[hs[x]]>sz[y]?hs[x]:y;
}
}
void dfs2(int x)
{
if(hs[x]) top[hs[x]]=top[x],dfs2(hs[x]);
for(int i=hd[x];i;i=nt[i])
{
int y=to[i];
if(!vv[i>>1]||y==fa[x]||y==hs[x]) continue;
top[y]=y,dfs2(y);
}
}
int glca(int x,int y)
{
while(top[x]!=top[y])
{
if(de[top[x]]<de[top[y]]) swap(x,y);
x=fa[top[x]];
}
return de[x]<de[y]?x:y;
}
void dfs3(int x)
{
for(int i=hd[x];i;i=nt[i])
{
int y=to[i];
if(!vv[i>>1]||y==fa[x]) continue;
dfs3(y),a[x]^=a[y],w[i>>1]=a[y];
}
}
int main()
{
n=rd(),m=rd();
for(int i=1;i<=m;++i) add(rd(),rd());
de[1]=1,dfs1(1);
top[1]=1,dfs2(1);
for(int i=1;i<=m;++i)
if(!vv[i])
{
w[i]=(1ull*rand()<<32)|1ull*rand();
int x=to[i<<1],y=to[i<<1|1],lca=glca(x,y);
if(y==lca) swap(x,y);
a[x]^=w[i],a[y]^=w[i];
if(x!=lca) a[lca]^=w[i];
}
dfs3(1);
q=rd();
int las=0;
while(q--)
{
memset(bs,0,sizeof(bs));
bool ok=0;
int kk=rd();
while(kk--)
{
uLL x=w[rd()^las];
for(int i=64;~i;--i)
if(x>>i&1)
{
if(!bs[i]){bs[i]=x;break;}
x^=bs[i];
if(!x) break;
}
ok|=!x;
}
las+=!ok;
puts(ok?"Disconnected":"Connected");
}
return 0;
}