70pts WA 求调
查看原帖
70pts WA 求调
258520
Leo_SZ楼主2024/6/8 19:41

提交记录:161613588

思路大概如下:

尝试从 xx 走到两个端点都是 ( 的边(记为L型边)反复横跳,再走到一个奇环绕 1 或 2 圈,再走到两个端点都是 ) 的边(记为R型边)反复横跳,然后到 yy。

如果中间没有奇环,则是二分图,要求 xx 和 yy 不在二分图的同一部。

如果不能到达L型或R型边,则是L型边和R型边交替。

  • bfs1: 建连通块1,防止 xx 到不了 yy。

  • bfs2: L型边和R型边交替形成的连通块2。

  • bfs3: 二分图染色找奇环,odd[i] 表示第 ii 个连通块1里面有奇环,否则 col[i] 标记点 i 在二分图的哪一部。

  • bfs4: 从L型边或R型边出发,找哪些(的点能到L型边,哪些)的点能到R型边。okl[i] 表示在 i 点之前至少要经过 okl[i] 个(的点,才能从 i 走到L型边,okr[i] 类似,用的是 dijkstra。

代码:

#include<bits/stdc++.h>
#define Maxn 500005
using namespace std;
int n,m,t;
char a[Maxn];
vector<int> e[Maxn];

int vis[Maxn],visl[Maxn],visr[Maxn];
queue<int> q;
priority_queue<pair<int,int> > ql,qr;

int scc1[Maxn],tot1;
void bfs1(int x){
	while(!q.empty()){ q.pop(); }
	scc1[x] = ++tot1;
	q.emplace(x); vis[x]=1;
	while(!q.empty()){
		x = q.front(); q.pop();
		for(int y : e[x])if(!vis[y]){
			scc1[y] = tot1;
			q.emplace(y); vis[y]=1;
		}
	}
}

int scc2[Maxn],tot2;
void bfs2(int x){
	while(!q.empty()){ q.pop(); }
	scc2[x] = ++tot2;
	q.emplace(x); vis[x]=1;
	while(!q.empty()){
		x = q.front(); q.pop();
		for(int y : e[x])if(!vis[y] && a[x] != a[y]){
			scc2[y] = tot2;
			q.emplace(y); vis[y]=1;
		}
	}
}

int col[Maxn],odd[Maxn];
void bfs3(int x){
	while(!q.empty()){ q.pop(); }
	col[x] = 0; q.emplace(x);
	while(!q.empty()){
		x = q.front(); q.pop();
		for(int y : e[x]){
			if(~col[y]){
				if(col[y] == col[x]){
					odd[scc1[x]] = 1; return;
				}
			} else {
				col[y] = col[x] ^ 1; q.emplace(y);
			}
		}
	}
}

int okl[Maxn],okr[Maxn];
void bfs4(int x){
	while(!q.empty()){ q.pop(); }
	q.emplace(x); vis[x]=1;
	while(!q.empty()){
		x = q.front(); q.pop();
		for(int y : e[x])if(!vis[y]){
			q.emplace(y); vis[y]=1;
			if(a[x] != a[y]){ continue; }
			if(a[x] == '('){
				okl[x] = okl[y] = 0;
				ql.emplace(0, x); ql.emplace(0, y);
			} else {
				okr[x] = okr[y] = 0;
				qr.emplace(0, x); qr.emplace(0, y);
			}
		}
	}
}
void dij(){
	int x,z;
	while(!ql.empty()){
		x = ql.top().second; ql.pop();
		if(visl[x]){ continue; }
		visl[x] = 1;
		for(int y : e[x]){
			z = max(0, okl[x] + ((a[y] == ')') ? 1 : -1));
			if(okl[y] > z){
				okl[y] = z; ql.emplace(-z, y);
			}
		}
	}
	while(!qr.empty()){
		x = qr.top().second; qr.pop();
		if(visr[x]){ continue; }
		visr[x] = 1;
		for(int y : e[x]){
			z = max(0, okr[x] + ((a[y] == '(') ? 1 : -1));
			if(okr[y] > z){
				okr[y] = z; qr.emplace(-z, y);
			}
		}
	}
}

int main(){
	scanf("%d%d%d%s",&n,&m,&t,a+1);
	int x,y,z;
	for(int i=1; i<=m; i++){
		scanf("%d%d",&x,&y);
		e[x].emplace_back(y);
		e[y].emplace_back(x);
	}
	
	for(int i=1; i<=n; i++)if(!vis[i]){
		bfs1(i);
	}
	
	memset(col, 0xff, sizeof(col));
	for(int i=1; i<=n; i++)if(col[i] == -1){
		bfs3(i);
	}
	
	memset(vis, 0, sizeof(vis));
	for(int i=1; i<=n; i++)if(!vis[i]){
		bfs2(i);
	}
	
	memset(vis, 0, sizeof(vis));
	memset(okl, 0x3f, sizeof(okl));
	memset(okr, 0x3f, sizeof(okr));
	for(int i=1; i<=n; i++)if(!vis[i]){
		bfs4(i);
		dij();
	}
	
	while(t--){
		scanf("%d%d",&x,&y);
		if(scc1[x] != scc1[y]){
			printf("0"); continue;
		}
		z = scc1[x];
		if(okl[x] || okr[y]){
			if(a[x]=='(' && a[y]==')' && scc2[x] == scc2[y]){
				printf("1");
			} else {
				printf("0");
			}
			continue;
		}
		if(odd[z] || col[x] != col[y]){
			printf("1");
		} else {
			printf("0");
		}
	}
	return 0;
}

Subtask #4 的三个点 WA 了,“read 0, expected 1”。

2024/6/8 19:41
加载中...