C - 小さな新城

説明

王があったならば、彼はリトル新と呼ばれます。ある日、彼は城を構築したかったので、設計者は、彼を主に伝え応接室をシンプルな設計図面の多くを与えました。新は少し二つの部屋のいずれか1つがある、唯一のパスを接続することができます願っています。今、小さな新あなたのデザインは、あなたがデザインが彼のアイデアを満たして判断するのに役立ちましょう。例えば以下の例では、最初のものが対象であるが、二つの経路(5-3-4及び5-6-4)5-4からあるので第二は、満たされません。
ここに画像を挿入説明ここに画像を挿入説明
入力

入力の複数のセットは、各ラインは第一整数M(M <100000)、二つの部屋チャネル接続の数を表す2つの整数の次のm行を含んでいます。余地は、少なくとも1以上、100,000ません。
出力

各データ出力ライン、もし小さな新の考え方に沿って、城、出力「はい」、そうでない場合は「いいえ」。
サンプル

入力

5
2 5
2 3
1〜3
3 6
4 6
6
1 2
1 3
3 4
3 5
5 6
6 4
出力

はい
いいえ
アイデア:出力がNOであれば、すべてのポイントが一緒に接続され、各グループは、このグループが以前互いに素セットに接続されていない見て前に判断を入力します、状況、NOはまた、これらの点の集合ではありません図通信がそうVIS []記録ポイントと、入力されたポイントかどうかを確認することは、接続されており、ルートどの点か否かを判断することはできません。

#include<stdlib.h>
#include<stdio.h>
#include<string.h>
int vis[100010];
int f[100010];
void init()
{
    for(int i=1;i<100010;i++)
        f[i] = i;
}
int getf(int v)
{
    if(f[v] == v)
        return v;
    else
    {
        f[v] = getf(f[v]);
        return f[v];
    }
}
void Merge(int u,int v)
{
    int t1,t2;
    t1 = getf(u);
    t2 = getf(v);
    if(t1 != t2)
    {
        f[t2] = t1;
    }
}
int main()
{
    int t;
    int u,v;
    while(~scanf("%d",&t))
    {
        int sum = 0;
        init();
        memset(vis,0,sizeof(vis));
        int flag = 0;
        for(int i=0;i<t;i++)
        {
            scanf("%d %d",&u,&v);
            vis[u] = vis[v] = 1;//标记这个点是否输入过
            if(f[u] == f[v])//防止成环
            {
                flag = 1;
            }
            else
                Merge(u,v);
        }
        for(int i=1;i<=100000;i++)
        {
            if(f[i] == i&&vis[i])
                sum++;
        }
        if(sum>1)
            flag = 1;
        if(flag == 0)
            printf("Yes\n");
        else
            printf("No\n");
    }

    return 0;

}

公開された177元の記事 ウォン称賛7 ビュー30000 +

おすすめ

転載: blog.csdn.net/Fusheng_Yizhao/article/details/104914763