bzoj3569 DZY Loves Chinese II

Keywords: C++

Title Link

problem

Give an undirected graph with \ (n \) points \ (m \) edges, and then ask \ (Q \) times. Each time you ask, \ (k \) edges will be given. You need to answer whether the undirected graph is connected or not after deleting the \ (k \) edges.

\(n\le 10^5,m\le 5\times 10^5,k\le 15\)

solution

First, find out a \ (dfs \) tree, and consider when the undirected graph will become disconnected.

If and only if there is a tree edge, the undirected graph is not connected when all the atavism edges covering the tree edge and the tree edge are deleted.

So how to judge whether there is such a tree edge? We can give each ancestor edge a random weight. The weight of each tree edge is the exclusive or sum of all the ancestor edges covering it. For a query, if the edge weight linear correlation of the query indicates that a subset exclusive or sum of 0 can be found, that is to say, the condition that the undirected graph is not connected is satisfied.

code

/*
* @Author: wxyww
* @Date:   2020-05-25 16:14:15
* @Last Modified time: 2020-05-25 16:47:10
*/
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#include<ctime>
#include<cmath>
using namespace std;
typedef long long ll;
const int N = 500100;
ll read() {
	ll x = 0,f = 1;char c = getchar();
	while(c < '0' || c > '9') {
		if(c == '-') f = -1; c = getchar();
	}
	while(c >= '0' && c <= '9') {
		x = x * 10 + c - '0'; c = getchar();
	}
	return x * f;
}
int n,m;
struct node {
	int v,nxt,w,id;
}e[N << 1];

int head[N],ejs = 1;
void add(int u,int v,int id) {
	e[++ejs].v = v;e[ejs].nxt = head[u];head[u] = ejs;e[ejs].id = id;
}
int vis[N],w[N];

void dfs1(int u,int fa) {
	vis[u] = 1;
	for(int i = head[u];i;i = e[i].nxt) {
		int v = e[i].v;
		if(e[i].w || v == fa) continue;
		if(vis[v]) {
			e[i].w = e[i ^ 1].w = rand() + 1;
			w[u] ^= e[i].w;w[v] ^= e[i].w;
			continue;
		}
		dfs1(v,u);
	}
}

void dfs2(int u,int fa) {
	for(int i = head[u];i;i = e[i].nxt) {
		int v = e[i].v;if(v == fa || e[i].w) continue;
		dfs2(v,u);
		w[u] ^= w[v];
		e[i].w = e[i ^ 1].w = w[v];
	}
}

int cnt,p[32];
int ins(int x) {

	// printf("!!!%d\n",x);
	
	for(int i = 30;i >= 0;--i) {
		if(x >> i & 1) {
			if(!p[i]) {p[i] = x;return 1;}
			x ^= p[i];
		}
	}
	return 0;
}
void solve() {
	int k = read(),flag = 0;
	for(int i = 1;i <= k;++i) {
		int x = read() ^ cnt;
		// printf("%d ",x);
		if(flag) continue;
		if(!ins(e[x << 1].w)) {
			puts("Disconnected");
			flag = 1;
			continue;
		}
	}
	// puts("");
	if(!flag) {
		++cnt;
		puts("Connected");
	}
}

int main() {
	// freopen("1.in","r",stdin);
	n = read(),m = read();

	for(int i = 1;i <= m;++i) {
		int u = read(),v = read();
		add(u,v,i);add(v,u,i);
	}

	dfs1(1,0);
	dfs2(1,0);
	int Q = read();
	while(Q--) {
		memset(p,0,sizeof(p));
		solve();
	}
	return 0;
}

Posted by melbell on Mon, 25 May 2020 07:05:33 -0700