atcoder #027 C. ABland Yard

版权声明:转载请注明出处 https://blog.csdn.net/qq_41593522/article/details/84196534

题意

给定一张图,每个点权值为A或B,随意遍历这张图,问能否拼出所有AB串

题解

结论:有形如AABB这样的环即可,否则不可以

用拓扑排序,把只与A连接或者只与B连接的点都去掉

剩下来的点都是既与A连,又与B连的点,就代表存在AABB这种类型的环

调试记录

拓扑排序要先vis[e[i].to] = true,不然会重复加

#include <cstdio>
#include <cstdlib>
#include <queue>
#define maxn 200005

using namespace std;

struct node{
	int to, next;
}e[maxn << 1];
int head[maxn], tot = 0;
void addedge(int u, int v){e[++tot].to = v, e[tot].next = head[u]; head[u] = tot;}

int n, m, Index[maxn][2];
char str[maxn];

bool vis[maxn];

int topo(){
	queue <int> q; while (!q.empty()) q.pop();
	
	for (int i = 1; i <= n; i++)
		if (!Index[i][0] || !Index[i][1]) q.push(i), vis[i] = true;
	
	int cnt = 0;
	while (!q.empty()){
		int cur = q.front(); q.pop();
		cnt++;
		
		for (int i = head[cur]; i; i = e[i].next){
			if (!vis[e[i].to] && !(--Index[e[i].to][str[cur] - 'A'])){
				q.push(e[i].to);
				vis[e[i].to] = true;
			}
		}
	}
	return cnt;
	
}

int main(){
	scanf("%d%d%s", &n, &m, str + 1);
	
	while (m--){
		int u, v; scanf("%d%d", &u, &v);
		addedge(u, v);
		addedge(v, u);
		Index[v][str[u] - 'A']++;
		Index[u][str[v] - 'A']++;
	}
	
	puts(topo() == n ? "No" : "Yes");
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41593522/article/details/84196534