AT4377 [AGC027C] ABland Yard
添加链接描述
当真是一道简单又复杂的题……
具体意思就是:给你一幅图,看看其中有没有一个子图,保证其中每个点都连着一个A和一个B。
至于做法嘛……看了下题解,大概思路就是:
将所有不满足条件的点剔除,剔除后又有一些点不满足条件了,又删掉,又有不满足条件的点,又删掉……
于是我们的任务就是把 当前不满足条件的点删掉,直到没有点不满足条件。
有人说这道题用拓扑来做……这个删点的过程也许就是拓扑的思想吧?
#include<bits/stdc++.h>
using namespace std;
const int N = 1e6 + 10;
int n, m, cnt;
int c[N], st[N], ab[N][2];
char s[N];
int to[N], ne[N], h[N], idx;
void add(int a, int b) {
to[idx] = b, ne[idx] = h[a], h[a] = idx ++;
}
void check(int x) {
if(ab[x][0] && ab[x][1]) return ;
st[x] = 0, cnt --;
for(int i = h[x]; ~i; i = ne[i]) {
int j = to[i];
ab[j][c[x]] --;
if(!st[j]) continue;
check(j);
}
}
int main() {
memset(h, -1, sizeof h);
cin >> n >> m;
cnt = n;
scanf("%s", s + 1);
for(int i = 1; i <= n; i ++) {
c[i] = s[i] - 'A';
st[i] = 1;
}
for(int i = 1; i <= m; i ++) {
int a, b; cin >> a >> b;
add(a, b), add(b, a);
ab[a][c[b]] ++;
ab[b][c[a]] ++;
}
for(int i = 1; i <= n; i ++)
if(st[i])
check(i);
if(cnt) cout << "Yes";
else cout << "No";
return 0;
}