Description
给定一个连通的无向图和若干小集合,每个小集合包含一些边。对于每个集合,你需要确定将集合中的边从原先的无向图中删除后该图是否保持连通。一个图是连通的当且仅当任意两个不同的点之间存在一条路径连接他们。
Input
输入的第一行包含两个整数
n
和
Output
输出
Sample Input
4 5
1 2
2 3
3 4
4 1
2 4
3
1 5
2 2 3
2 1 2
Sample Output
Connected
Disconnected
Connected
Solution
先找到原图的一个生成树,给非树边随机边权,定义点权为以其为端点的非树边边权异或和,给树定向之后,树边的权值为其深度较深的端点点权,这样如果删去的边集中存在一个子集使得其权值异或和为 0 <script type="math/tex" id="MathJax-Element-21">0</script>,则说明一条树边及其周围的非树边全部被删掉,由于边权是随机的所以出错率很小
Code
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<ctime>
using namespace std;
namespace fastIO
{
#define BUF_SIZE 100000
//fread -> read
bool IOerror=0;
inline char nc()
{
static char buf[BUF_SIZE],*p1=buf+BUF_SIZE,*pend=buf+BUF_SIZE;
if(p1==pend)
{
p1=buf;
pend=buf+fread(buf,1,BUF_SIZE,stdin);
if(pend==p1)
{
IOerror=1;
return -1;
}
}
return *p1++;
}
inline bool blank(char ch)
{
return ch==' '||ch=='\n'||ch=='\r'||ch=='\t';
}
inline void read(int &x)
{
char ch;
while(blank(ch=nc()));
if(IOerror)return;
for(x=ch-'0';(ch=nc())>='0'&&ch<='9';x=x*10+ch-'0');
}
#undef BUF_SIZE
};
using namespace fastIO;
const int maxn=100005,maxm=200005;
struct node
{
int v,next;
}edge[maxm*2];
int n,m,q,res,vis[maxn],val[maxn],weight[maxm],tot,head[maxn],base[33];
void add(int u,int v)
{
edge[++tot].v=v,edge[tot].next=head[u],head[u]=tot;
}
void dfs(int u,int fa)
{
vis[u]=res++;
for(int i=head[u];i;i=edge[i].next)
{
int v=edge[i].v;
if(v==fa)continue;
if(!vis[v])
{
dfs(v,u);
weight[i/2]=val[v];
val[u]^=val[v];
}
else if(vis[u]>vis[v])
{
weight[i/2]=rand()+1;
val[u]^=weight[i/2];
val[v]^=weight[i/2];
}
}
}
int main()
{
srand(19971109);
read(n);read(m);//scanf("%d%d",&n,&m);
tot=res=1;
while(m--)
{
int u,v;
read(u);read(v);//scanf("%d%d",&u,&v);
add(u,v),add(v,u);
}
dfs(1,0);
int num=0;
read(q);//scanf("%d",&q);
while(q--)
{
int k,temp,flag=0;
read(k);//scanf("%d",&k);
memset(base,0,sizeof(base));
while(k--)
{
read(temp);//scanf("%d",&temp);
temp=weight[temp];
for(int i=30;i>=0;i--)
if(temp>>i&1)
{
if(!base[i])
{
base[i]=temp;
break;
}
else temp^=base[i];
}
if(!temp)flag=1;
}
if(flag)printf("Disconnected\n");
else printf("Connected\n"),num++;
}
return 0;
}