AT4377 [AGC027C] ABland Yard ——标签: #拓扑

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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值