#HDU 1269迷路城(tarjan)

問題の説明

方向の小さなギリシャの感覚を訓練するために、ガルドンは室内N(N <= 10000)及びMチャネル(Mは<= 100000)、各チャネルが呼び出された場合には、一方向性であり、大規模な城を建て部屋Aと部屋Bの連通路は、部屋Bには、このチャネルを介して説明した客室でのみ到達することができますが、それを介してBの部屋に到達することができます部屋を示すものではありません。任意のiとjのために、部屋から部屋jへの少なくとも一つのパスがあるi、jはまた、部屋からのパスをしている可能性がありますガルドンは、すなわち、任意の二つの部屋が相互接続されているかどうかを確認するためのプログラムを書くことをお願いする必要があります部屋私。

 

 

入力

N及びM、次のMラインの各2つの数AおよびBと、Bの部屋の部屋からチャネルを表すことができる:最初の行は、2つの入力数値があり、入力データの複数のセットを含みます。2ゼロでファイルと終了。

 

 

出力

任意の二つの部屋を互いに、および出力に接続されている場合、入力データの各セットに対して、「はい」、そうでない場合、「いいえ」を出力します。

 

 

サンプル入力

 

3 3 1 2 2 3 3 1 3 3 1 2 2 3 3 2 0 0

 

 

サンプル出力

 

はい・いいえ

所与言うまでもなくタイトル効果が、それは図に任意の二つの通信か否かが判断されます。

アイデア:最初、Floyedでこの質問を見たデータの読み取りがアイデアをあきらめた後、あなたが考えることができます最初のポイントではありませんし、それを縮小floyed?そして、ああノックノック、我々は実際には、そんなにないトラブル、ことがわかりました。任意の時点で通信することができ、彼自身がリングでない場合は、何らかの形の外またはに、リングでは0であることを唯一の場合は、そこにある、彼は他のポイントや到着の他のポイントに到達することはできません。だから、ビューの直接還元ポイントが新しいポイントJiuhaolaだけではありません!ただ、それが結果的に今floyedQAQを見ていると思うfloyed学習

ACコード:

#include<iostream>
#include<cstring>
#include<stack>
using namespace std;
const int maxn = 1e5 + 5;

struct node
{
    int v, next;
}e[maxn];
int dfn[maxn], low[maxn], n, m, cnt, tot;
int head[maxn], in[maxn], suo[maxn], scnt;
bool vis[maxn];
stack <int> st;
void init() {
    memset(head, -1, sizeof(head));
    memset(e, 0, sizeof(e));
    memset(suo, 0, sizeof(suo));
    memset(dfn, 0, sizeof(dfn));
    memset(low, 0, sizeof(low));
    memset(vis, 0, sizeof(vis));
    memset(in, 0, sizeof(in));
    cnt = tot = scnt = 0;
}
void add (int from, int to) {
    e[++cnt].v = to;
    e[cnt].next = head[from];
    head[from] = cnt;
}
void tarjan(int x) {
    dfn[x] = low[x] = ++tot;
    vis[x] = 1;
    st.push(x);
    for (int i = head[x]; i != -1; i = e[i].next) {
        if (!dfn[e[i].v]) {
            tarjan(e[i].v);
            low[x] = min (low[x], low[e[i].v]);
        }
        else if (vis[e[i].v]) low[x] = min (low[x], dfn[e[i].v]);
    }
    if (dfn[x] == low[x]) {
        scnt++;
        int k;
        do {
            k = st.top();
            st.pop();
            suo[k] = scnt;
            vis[k] = 0;
        }
        while (k != x);
    }
}

int main()
{
    while (cin >> n >> m && n + m) {
        init();
        for (int i = 0; i < m; i++) {
            int ui, vi;
            cin >> ui >> vi;
            add (ui, vi);
        }
        for (int i = 1; i <= n; i++) {
            if (!dfn[i]) tarjan(i);
        }
        if (scnt == 1) cout << "Yes" << endl;
        else cout << "No" << endl;
    }
    return 0;
}

 

おすすめ

転載: blog.csdn.net/weixin_43851525/article/details/91363033