Semiconnected--強連通縮點

1451: Semiconnected

時間限制: 1 Sec  內存限制: 32 MB
提交: 79  解決: 20

題目描述

For a directed graph G = (V, E), if for all pairs of nodes u,v, u can always reach v or v can always reach u , then we call this a Semiconnected graph. Now you are given a directed graph, you should tell us whether it is a Semiconnected graph. If it is, output “yes”, or else“no”.

輸入

There are several test cases, for each test case, there are two integers in the first line, n and m n(n<=10000) ,m(m<=50000) , means that there are n nodes and m edges in this graph. The nodes are numbered from 1 to n. Then m lines each with two integers u and v means there is an edge from u to v.

輸出

For each test case, output “yes” if it is a Semiconnected graph, or else “no” instead.

樣例輸入

4 3
1 2
2 3
3 4
4 3
1 2
2 3
4 3

樣例輸出

yes
no

題意:給你一個有向圖,若從圖中任意兩個點u,v。都有從u到v的路徑,或者從v到u的路徑,則該圖爲半連通的,是則輸出yes,不是則輸出no

思路:若該圖符合以上情況,

        1:入度爲0的點多於一個,不符合。

        2:對該圖進行縮點後,若爲半連通圖,則當前的圖爲一條直線,統計新圖中入度,出度爲0的點是不是都只有一個即可。

代碼如下:

#include "stdio.h"  //強連通縮點後,判斷新圖中入度爲0,出度爲0的點是否都只有一個
#include "string.h"
#include "vector"
#include "stack"
using namespace std;

#define N 10005
#define M 50005

struct node
{
    int x,y;
    int next;
}edge[M];
int idx,head[N];
void Init(){ idx=0; memset(head,-1,sizeof(head)); }
void Add(int x,int y)
{
    edge[idx].x=x; edge[idx].y=y;
    edge[idx].next=head[x]; head[x]=idx++;
}

int n;
int dfs_clock;
bool mark[N];
int scc_cnt;
int belong[N];
stack<int> q;
int num[N];
int low[N],dfn[N];
int MIN(int a,int b) { return a<b?a:b; }

void DFS(int x)
{
    int i,y;
    q.push(x);
    mark[x] = true;
    low[x] = dfn[x] = ++dfs_clock;
    for(i=head[x]; i!=-1; i=edge[i].next)
    {
        y=edge[i].y;
        if(!dfn[y])
        {
            DFS(y);
            low[x] = MIN(low[x],low[y]);
        }
        else if(mark[y])
            low[x] = MIN(dfn[y],low[x]);
    }
    if(low[x]==dfn[x])
    {
        int temp;
        scc_cnt++;
        while(1)
        {
            temp = q.top();
            q.pop();
            belong[temp] = scc_cnt;
            num[scc_cnt]++;
            mark[temp] = false;
            if(temp==x) break;
        }
    }
}

int ru_du[N],chu_du[N];

void Solve(int id)
{
    int i;
    int x,y;
    dfs_clock = scc_cnt = 0;
    memset(dfn,0,sizeof(dfn));
    memset(num,0,sizeof(num));
    memset(belong,0,sizeof(belong));
    memset(mark,false,sizeof(mark));
    DFS(id);
    for(i=1; i<=n; ++i)
    {
        if(!dfn[i])
            DFS(i);
    }
    memset(ru_du,0,sizeof(ru_du));
    memset(chu_du,0,sizeof(chu_du));
    for(i=0; i<idx; ++i)
    {
        x = edge[i].x;
        y = edge[i].y;
        if(belong[x]!=belong[y])
        {
            chu_du[belong[x]]++;
            ru_du[belong[y]]++;
        }
    }
    int ru_0=0;
    int chu_0=0;
    for(i=1; i<=scc_cnt; ++i)
    {
        if(ru_du[i]==0)
            ru_0++;
        if(chu_du[i]==0)
            chu_0++;
    }
    if(ru_0==1 && chu_0==1)
        printf("yes\n");
    else
        printf("no\n");
}

int ru[N],chu[N];

int main()
{
    int i,m;
    int x,y;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        Init();
        memset(ru,0,sizeof(ru));
        memset(chu,0,sizeof(chu));
        while(m--)
        {
            scanf("%d%d",&x,&y);
            Add(x,y);
            chu[x]++;
            ru[y]++;
        }
        int ans=0,id=1;
        for(i=1; i<=n; ++i)
        {
            if(ru[i]==0)
            {
                ans++;
                id=i;
            }
        }
        if(ans>1) { printf("no\n"); continue; }
        Solve(id);
    }
    return 0;
}








發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章