hdu1269 并查集 强联通

 

#include<iostream>//并查集

using namespace std;

#define max 10010

int n,father1[max],father2[max];

 

int find1(int x)

{

      

       if(father1[x]!=x)

              return  father1[x]=find1(father1[x]);

       else

              return x;

}

 

int find2(int x)

{    

       if(father2[x]!=x)

              return father2[x]=find2(father2[x]);

       else

              return x;

}

 

void unite(int a,int b)

{

       int i,j;

       if(a!=n)

       {

              i=find1(a);

              j=find1(b);

              if(i!=j)

                     father1[a]=b;

       }

       if(b!=n)

       {

              i=find2(a);

              j=find2(b);

              if(i!=j)

                  father2[b]=a;

       }

}

 

int main()

{

       int i,j,m,a,b;

       bool ok;

       while(cin>>n>>m && m+n)

       {

              ok=true;

              for(i=1;i<=n;i++)

              {

                     father1[i]=father2[i]=i;

              }

             

              for(i=1;i<=m;i++)

              {

                     cin>>a>>b;

                     unite(a,b);

              }

              for(i=1;i<=n;i++)

                     if(find1(i)!=n || find2(i)!=n)

                     {  ok=false;break;}

 

                     if(ok)

                            cout<<"Yes"<<endl;

                     else

                            cout<<"No"<<endl;

       }

       return 0;

}

//法二 强联通

#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
#define M 100005
#define N 10005

struct ss {
    int to;
    int next;
} edge[M];
int head[N];
int top, stack[N], mlik[N], indx[N], cnt, tot, belong[N], intime;
bool mark[N];

void add(int x, int y) {
    edge[tot].to = y,edge[tot].next = head[x],head[x] = tot++;
}

void Tarjan(int x) {
    mark[x] = true;
    stack[++top] = x;
    mlik[x] = indx[x] = ++intime;
    int k, y;
    for (k = head[x]; k != -1; k = edge[k].next) {
        y = edge[k].to;
        if (!indx[y]) {
            Tarjan(y);
            if (mlik[x] > mlik[y])
                mlik[x] = mlik[y];
        } else if (mark[y] && mlik[x] > indx[y])mlik[x] = indx[y];
    }
    if (mlik[x] == indx[x]) {
        cnt++;
        do {
            y = stack[top--];
            mark[y] = false;
            belong[y] = cnt;
        } while (y != x);
    }
}

int main() {
    int n, m, a, b, i;
    while (scanf("%d %d", &n, &m), n + m) {
        tot = 1;
        memset(head, -1, sizeof (head));
        while (m-- && scanf("%d %d", &a, &b))
            add(a, b);
        memset(indx, 0, sizeof (indx));
        cnt = intime = top = 0;
        for (i = 1; i <= n; i++)
            if (!indx[i])Tarjan(i);
        if (cnt ==1 )printf("Yes/n");
        else printf("No/n");
    }
    return 0;
}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值