U119054 边双连通分量 求助
  • 板块学术版
  • 楼主qwe5130
  • 当前回复0
  • 已保存回复0
  • 发布时间2020/8/27 13:08
  • 上次更新2023/11/6 19:11:18
查看原帖
U119054 边双连通分量 求助
214237
qwe5130楼主2020/8/27 13:08
#include <stdio.h>
#include <algorithm>
#include <vector>
#include <string.h>
using namespace std;
const int N = 5e5 + 7, M = 1e6 + 7;
int bccno[N], bccCount;
int low[N], dfn[N], dfs_clock;
int h[N], w[N], ne[M], e[M], cnt;
int bridge[N], ans[N];
void addEdge(int u, int v){
	e[cnt] = v;	
	ne[cnt] = h[u];
	h[u] = cnt ++;
}
void dfs_bridge(int u, int f){
	dfn[u] = low[u] = ++ dfs_clock;
	for (int i = h[u]; ~i; i = ne[i]){
		int v = e[i];
		if (!dfn[v]){
			dfs_bridge(v, u);
			low[u] = min(low[u], low[v]);
			if (low[v] > dfn[u]){
				//找到桥, 双向边都标记为桥
				bridge[i] = 1;
				bridge[i^1] = 1; 
			}
		}
		else if ( v !=  f)
			low[u] = min(low[u], dfn[v]);
	}
}
void dfs1(int u){
	bccno[u] = bccCount;
	ans[bccCount] ^= w[u];
	for (int i = h[u]; ~i; i = ne[i]){
		if (bridge[i]) continue;
		int v = e[i];
		if (bccno[v] == 0) dfs1(v);
	}
}
int main (){
	int n, m;
	scanf ("%d%d", &n, &m);
	memset(h, - 1, sizeof h);
	memset(bridge, 0, sizeof bridge);
	memset(bccno, 0, sizeof bccno);
	for (int i = 1; i <= n; i ++ )
		scanf ("%d", &w[i]);	
	for (int i = 0;  i < m; i ++ ){
		int u, v;
		scanf ("%d%d", &u, &v);
		addEdge(u, v);
		addEdge(v, u);
	}
	for (int i = 1; i <= n; i ++ ){
		if (dfn[i] == 0)
			dfs_bridge(i, 0);
	}
	bccCount = 0;
	for (int i = 1; i <= n; i ++ ){
		if (bccno[i] == 0){
			bccCount ++ ;
			dfs1(i);
		}
	}
	sort(ans + 1, ans + bccCount + 1);
	for (int i = 1; i <= bccCount; i ++ )
		printf ("%d\n", ans[i]);
	return 0;
} 
2020/8/27 13:08
加载中...