タイトル
ご存知のとおり、TTは魔法の猫を飼っている猫好きです。
ある日、TTはステーションBで猫の試合を見ました。合計N匹の猫がいて、1、2、3、...、Nの番号が付けられています。ゲームの後、Upホストはすべての猫を前から後ろにランク付けし、お気に入りの干物を配布します。残念ながら、現時点では、TTの電子機器はデスマートの宇宙線に見舞われ、インターネットにアクセスすることすらできず、当然ながら最終的な授賞式は行われませんでした。
幸いなことに、TTの魔法の猫は各ゲームの結果を記録しましたが、彼は最小の辞書式順序のシーケンスを決定するようにプログラムしたいと考えています。
入力
入力のグループがいくつかあり、各グループの最初の行は2つの数値N(1 <= N <= 500)、Mです。Nは猫と猫の数を表し、Mは入力データの次のM行を表します。次のM行のデータでは、各行に2つの整数P1、P2もあり、番号P1の猫が番号P2の猫に勝つことを意味します。
出力
要件を満たすランキングを付けます。出力時に猫の番号の間にスペースがあり、最後のものの後にスペースがありません!
その他の注意事項:条件を満たすランキングは一意ではない可能性があります。現時点では、番号が最も小さいチームを最初に出力する必要があります。入力データが正しいことが保証されます。つまり、入力データにより、要件を満たすランキングが存在することが保証されます。
入力例
4 3
1 2
2 3
4 3
出力例
1 2 4 3
アイデア
猫の勝敗関係は、有向グラフのエッジ、勝ちb、つまり、aからbに向かうエッジがあり、これらのポイントのトポロジーシーケンスが最終的なランキングであると考えることができます。最小の辞書式順序でトポロジーシーケンスを出力するには、最小ヒープを使用してトポロジーシーケンスを見つけることができます。
コード
#include <iostream>
#include <queue>
#include <algorithm>
#include <string.h>
using namespace std;
const int maxn = 505;
struct edge
{
int to, next;
}e[maxn * 2];
int n, m, inde[maxn], head[maxn], tot;
void add(int x, int y)
{
e[++tot].to = y;
e[tot].next = head[x];
head[x] = tot;
}
void toposort()
{
priority_queue<int>q;
while (!q.empty())
q.pop();
for (int i = 1; i <= n; i++)
if (inde[i] == 0)
q.push(-i);
vector<int> ans;
while (!q.empty())
{
int u = -q.top();
q.pop();
ans.push_back(u);
for (int i = head[u]; i!=0; i = e[i].next)
if (--inde[e[i].to] == 0)
q.push(-e[i].to);
}
for (int i = 0; i < ans.size() - 1; i++)
cout << ans[i] << " ";
cout << ans[ans.size() - 1] << endl;
}
int main()
{
while (scanf_s("%d%d",&n,&m)!=EOF)
{
memset(head, 0, sizeof(head));
memset(inde, 0, sizeof(inde));
tot = 0;
for (int i = 1; i <= m; i++)
{
int a, b;
scanf_s("%d%d", &a, &b);
add(a, b);
inde[b]++;
}
toposort();
}
return 0;
}