1. 程式人生 > >atcoder #027 C. ABland Yard

atcoder #027 C. ABland Yard

題意

給定一張圖,每個點權值為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; }