トピックの背景
あなたは食物連鎖にそれを知っていますか?デリア生物学的試験、彼女は常にいくつかまたはいくつかは、いくつかの欠落を繰り返しているため、すべての間違った食物連鎖をカウントの対象。そこで彼女が来て、あなたを助けるが、あなたはああではないでしょう!彼女を助けるためにプログラムを書きます。
タイトル説明
あなたの食物網を与え、あなたは食物網における最大の食物連鎖の数を尋ねました。
(を参照ここで、「最大の食物連鎖」、生物学的な意味での食物連鎖、つまり、一番左の生産者は、ほとんどの消費者は権利ではありません他の種を捕食ではありませんが、他の生物による捕食です。)
デリアは非常に急務となっているので、あなただけの1秒を持っています。
この結果は大きすぎる可能性がありますので、あなただけの80112002金型の総出力を必要とします。
入力形式
最初の行、2つの正の整数N、M、及びN食べ食品関係の数mの種を表します。
2つの正の整数の次のm行は、Aは、食べ及びB.生物を食べる表します
出力フォーマット
整数、食物連鎖の結果、80112002型の最大数に並びます。
エントリー
5 7
1 2
1 3
2 3
3 5
2 5
4 5
3 4
輸出
5
説明/ヒント
各テストポイントは、次の規則を満たします:
[補足]
中央データは、要件の生物学を満たすためには表示されません。(おかげで@AKEE)
ソリューション:
トポロジカルソートO(m)の統計情報を表示します。
他の誰か(0度)から食べることができないから始まり、1で示され、常に更新、すべての隣に渡し、右のポイント値+右この時点を過ぎて渡された値をしましょう。
最後に、すべてのポイントが最大値を満たすために食物連鎖の外ではありません達しました。
#include <iostream>
#include <cstdio>
#include <queue>
using namespace std;
const int N = 5e3 + 5, mod = 80112002;
int n, m, indeg[N], outdeg[N], a, b, f[N], ans;
int map[N][N];
queue <int> q;
int main(){
cin >> n >> m;
for(int i = 1;i <= m;i ++){
scanf("%d%d", &a, &b);
map[a][b] = 1; outdeg[a] ++; indeg[b] ++;
}
for(int i = 1;i <= n;i ++) if(indeg[i] == 0) f[i] = 1, q.push(i);
while(! q.empty()){
int tp = q.front(); q.pop();
for(int to = 1;to <= n;to ++){
if(map[tp][to] == 0)continue;
(f[to] += f[tp]) %= mod;
indeg[to] --;
if(indeg[to] == 0) q.push(to);
if(indeg[to] == 0&&outdeg[to] == 0) {
(ans += f[to]) %= mod;
continue;
}
}
}
cout << ans;
}