字符王国
题目链接:51nod 3188
题目大意
给你一个有向图,然后点有字符,然后要你找一条路径,它里面出现次数最多的字符出现次数最多。
输出这个最多的次数。
思路
教练的任务。
就直接先判掉有环的。
然后直接用拓扑排序 DP 一下即可。(这里也可以顺便判环)
代码
#include<queue>
#include<cstdio>
#include<vector>
#include<iostream>
using namespace std;
const int N = 300000 + 100;
int n, m, x, y, ru[N], cnt;
int f[N][26];
char s[N];
vector <int> G[N];
queue <int> q;
int main() {
scanf("%d %d", &n, &m);
scanf("%s", s + 1);
for (int i = 1; i <= m; i++) {
scanf("%d %d", &x, &y);
G[x].push_back(y); ru[y]++;//建图以及计算一个点的入度
}
int ans = 0;//拓扑排序
for (int i = 1; i <= n; i++)
if (!ru[i]) q.push(i), cnt++;
while (!q.empty()) {
int now = q.front(); q.pop();
f[now][s[now] - 'a']++;//加上这个点的符号
for (int i = 0; i < 26; i++) ans = max(ans, f[now][i]);//统计答案
for (int i = 0; i < G[now].size(); i++) {
int x = G[now][i]; ru[x]--;
if (!ru[x]) q.push(x), cnt++;
for (int j = 0; j < 26; j++)//DP转移
f[x][j] = max(f[x][j], f[now][j]);
}
}
if (cnt != n) {//没有到 n 个点代表拓扑排序没有结果,说明出现了环,所以是无解的(或者说是INF的)
printf("-1"); return 0;
}
printf("%d", ans);
return 0;
}