ディレクトリ
城ラビリンス(強く通信)
タイトル
方向の小さなギリシャの感覚を訓練するために、ガルドンは室内N(N <= 10000)及びMチャネル(Mは<= 100000)、各チャネルが呼び出された場合には、一方向性であり、大規模な城を建て部屋Aと部屋Bの連通路は、部屋Bには、このチャネルを介して説明した客室でのみ到達することができますが、それを介してBの部屋に到達することができます部屋を示すものではありません。任意のiとjのために、部屋から部屋jへの少なくとも一つのパスがあるi、jはまた、部屋からのパスをしている可能性がありますガルドンは、すなわち、任意の二つの部屋が相互接続されているかどうかを確認するためのプログラムを書くことをお願いする必要があります部屋私。
入力
データの複数のセットを含む入力は、入力の最初の行は、2つの数値を有する:N及びM、次のMラインの各2つの数AおよびBと、Bの部屋の部屋からチャネルを表すことができます。2ゼロでファイルと終了。
出力
任意の二つの部屋が相互接続されている場合は、入力データの各セットについては、の出力が「はい」、そうでない場合は「いいえ」を出力します。
入力サンプル
3 3
1 2
2 3
3 1
3 3
1 2
2 3
3 2
0 0
サンプル出力
はい
いいえ
問題の意味
そして唯一の強連結成分かどうかを決定します
問題の解決策
#include <cstdio>
#include <algorithm>
#include <string.h>
#include <vector>
#include <iostream>
#include <stack>
#define N 75005
using namespace std;
vector<int> eg[N];
stack<int> sk;
int idx = 0;
int dfn[N], low[N], ins[N], cnt = 0;
void tarjan(int u)
{
dfn[u] = low[u] = ++idx;
sk.push(u);
ins[u] = 1;
for (int v : eg[u])
{
if (!dfn[v])
{
tarjan(v);
low[u] = min(low[u], low[v]);
}
else if (ins[v])
{
low[u] = min(low[u], dfn[v]);
}
}
int tem;
if (dfn[u] == low[u])
{
cnt++;
do
{
tem = sk.top();
sk.pop();
ins[tem] = 0;
} while (tem != u);
}
}
int main()
{
int n, m, x, y;
while (scanf("%d%d", &n, &m) && n)
{
memset(ins, 0, sizeof(ins));
memset(low, 0, sizeof(low));
memset(dfn, 0, sizeof(dfn));
for (int i = 0; i < m; i++)
{
cin >> x >> y;
eg[x].push_back(y);
}
idx = 0;
cnt = 0;
for(int i=1;i<= n;i++)
if(!dfn[i])
tarjan(i);
if (cnt == 1)
{
cout << "Yes" << endl;
}
else
{
cout << "No" << endl;
}
for (int i = 1; i <= n; i++)
{
eg[i].clear();
}
}
}