POJ 2762 Going from u to v or from v to u(弱连通分量)

来源:互联网 发布:淘宝推广pid 编辑:程序博客网 时间:2024/04/30 00:05

弱连通分量的概念是把有向图变成无向图之后,图是连通的。

这里问的是如果x到y或y到x,即有一个条件成立即可,那么先缩点,同一个强连通分量里的点是一定互相可达的,所以不用讨论,只需要看不同强连通分量的关系。

现在连上桥之后,只需要判断出入度为0的点相加是否大于2即可判断题目条件。

因为如果有超过一个点入度为0,这些点之间是相互不可达的,同理可证出度为0,那么只能有一个入度为0的点,一个出度为0的点,相加等于2则条件成立,输入yes,否则输出no。

////  main.cpp//  Richard////  Created by 邵金杰 on 16/8/18.//  Copyright © 2016年 邵金杰. All rights reserved.//#include<iostream>#include<cstdio>#include<vector>#include<cstring>#include<algorithm>using namespace std;const int maxn=1000+10;int instack[maxn],dfn[maxn],low[maxn],belong[maxn],in[maxn],out[maxn];vector<vector<int> > G(maxn);vector<int> s;int n,m;int cnt=0,idex=0;void Tarjan(int u){    dfn[u]=low[u]=++idex;    s.push_back(u);    instack[u]=1;    for(int i=0;i<G[u].size();i++)    {        int v=G[u][i];        if(!dfn[v])        {            Tarjan(v);            low[u]=min(low[u],low[v]);        }        else if(instack[v])        {            low[u]=min(low[u],dfn[v]);        }    }    if(dfn[u]==low[u])    {        cnt++;        int p;        do{            p=s[s.size()-1];            instack[p]=0;            belong[p]=cnt;            s.pop_back();        }while(u!=p);    }}bool Count(){    memset(in,0,sizeof(in));    memset(out,0,sizeof(out));    for(int i=1;i<=n;i++)    {        for(int j=0;j<G[i].size();j++)        {            int v=G[i][j];            if(belong[i]!=belong[v])            {                out[belong[i]]++;                in[belong[v]]++;            }        }    }    int ans=0;    for(int i=1;i<=cnt;i++)    {        if(!out[i]) ans++;        if(!in[i]) ans++;    }    if(ans>2) return false;    return true;}int main(){    int t;    scanf("%d",&t);    while(t--)    {        scanf("%d%d",&n,&m);        cnt=0;idex=0;        s.clear();        for(int i=1;i<=n;i++) G[i].clear();        memset(dfn,0,sizeof(dfn));        memset(low,0,sizeof(low));        memset(instack,0,sizeof(instack));        memset(belong,0,sizeof(belong));        int a,b;        for(int i=0;i<m;i++)        {            scanf("%d%d",&a,&b);            G[a].push_back(b);        }        for(int i=1;i<=n;i++)        {            if(!dfn[i])            {                Tarjan(i);            }        }        if(Count()) printf("Yes\n");        else printf("No\n");    }    return 0;}


0 0
原创粉丝点击