题目大意:
有 个竹签,有 组限制关系 ,表示竹签 压着 ,问在不影响平衡的情况下,你最多能连续拿出多少个竹签。
分析:
把限制关系
,变成一条
的有向边,
那么就是直接拓扑排序即可,
拓扑排序是这样一个东西:
①找入度为
的点加入队列
②并将所有与这个点有关的连边删去
③重复①②
那么你将所有进过队列的点统计一下数目即可。
因为每次你入度为
就是你没有被别的竹签限制
代码:
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#define N 1000005
using namespace std;
queue <int> Q;
struct Node { int To, nxt; }e[N];
int Rd[N], ls[N], n, m, cnt, ans;
void Addedge(int u, int v) {
e[++cnt].To = v, e[cnt].nxt = ls[u], ls[u] = cnt;
}
void Top_sort() {
for (int i = 1; i <= n; i++)
if (!Rd[i]) ans++, Q.push(i);
while (!Q.empty()) {
int u = Q.front();
Q.pop();
for (int i = ls[u]; i; i = e[i].nxt) {
int v = e[i].To;
if (!(--Rd[v])) ans++, Q.push(v);
}
}
}
int main() {
freopen("mikado.in", "r", stdin);
freopen("mikado.out", "w", stdout);
scanf("%d %d", &n, &m);
int u, v;
for (int i = 1; i <= m; i++) {
scanf("%d %d", &u, &v);
Addedge(u, v), Rd[v]++;
}
Top_sort();
printf("%d\n", ans);
return 0;
}