CodeForces - 1494E A-Z Graph(思维)
题目大意
给你一些操作,可以在图中添加一条原来没有的有向边,也可以删除一条存在的有向边,每一个边有一个边权,为一个字符。查询操作问是否存在一个长度为k的序列,k中可以有重复的点,并且每个相邻的点在图上也是相邻的,这个序列按照从左到右的顺序访问和从右到左的顺序访问所得到的字符串是一样的。
解题思路
如果k是奇数的话,至少需要有两个点满足可以互相访问,并且只有一个就行了,这样就能[1,2,1,2,1]这样构造答案。
如果k是偶数的话,考虑中间那条边,肯定需要一条来回都是同样的字符的边才行,并且只有这一条边就行了。所以做法就是统计两种边的数量。
代码
const int maxn = 2e5+10;
int n, m;
map<P, char> mp;
int main() {
cin >> n >> m;
int c1 = 0, c2 = 0;
for (int i = 1; i<=m; ++i) {
char op[5];
scanf("%s", op);
if (op[0]=='+') {
int u, v; char ch[5];
scanf("%d %d %s", &u, &v, ch);
if (mp[{v, u}]) {
++c1;
if (mp[{v, u}]==ch[0]) ++c2;
}
mp[{u,v}] = ch[0];
}
else if (op[0]=='-') {
int u, v; scanf("%d%d", &u, &v);
if (mp[{u, v}] && mp[{v, u}]) {
--c1;
if (mp[{u, v}]==mp[{v, u}]) --c2;
}
mp[{u, v}] = 0;
}
else {
int k; scanf("%d", &k);
if (k&1) printf("%s\n", c1 ? "YES":"NO");
else printf("%s\n", c2 ? "YES":"NO");
}
}
return 0;
}