hdu 1269

来源:互联网 发布:windows player手机版 编辑:程序博客网 时间:2024/05/18 22:52

主题思想: 图论 ,判断一个图是否是强联通,以及求图的强联通分量。

判断一个图是否是强联通的,有两种算法,一个是kosaraju 算法,和 tarjan 算法,
kosaraju是一个需要建立逆图的算法,这里介绍tarjan算法
核心思想是依据DFS. 更新LOW[i] 。

具体参考博客:

http://blog.csdn.net/w571523631/article/details/77990705
https://www.byvoid.com/zhs/blog/scc-tarjan

tarjan 代码:

int LOW[maxn];int DFN[maxn];int belong[maxn];bool  instack[maxn];vector<int> g[maxn];  //int Index=0;int bnt=0;int n,m;stack<int> st;void tarjan(int i){    DFN[i]=LOW[i]=++Index;    instack[i]=true;    st.push(i);    int len=g[i].size();    for(int j=0;j<len;j++){        // DFN[i] stands for the n-th that visited ,if DFN[i] is 0 means not visited;        if(!DFN[g[i][j]]){            tarjan(g[i][j]);            //LOW[i]=min(LOW[i],LOW[g[i][j]]);            if(LOW[i]>LOW[g[i][j]]) LOW[i]=LOW[g[i][j]];        }else if(instack[g[i][j]]&&LOW[i]>DFN[g[i][j]]){            LOW[i]=DFN[g[i][j]];        }    }    //    if(LOW[i]==DFN[i]){        bnt++;        int tmp;        while(st.top()!=i){            tmp=st.top();            belong[tmp]=bnt;            instack[tmp]=false;            st.pop();        }        if(st.top()==i){            st.pop();            belong[i]=bnt;            instack[i]=false;        }    }}bool solve(){    bnt=0;    Index=0;    //init    while(!st.empty())st.pop();    for(int i=0;i<=n;i++){        DFN[i]=0;        LOW[i]=0;        instack[i]=false;        belong[i]=0;    }    for(int i=1;i<=n;i++){        if(!DFN[i]){            tarjan(i);        }    }    //    if(bnt==1) return true;    else return false;}

AC代码:

#include <iostream>#include<cstdio>#include<cstring>#include<string>#include<stack>#include<vector>#include<algorithm>using namespace std;const int maxn=10005;int LOW[maxn];int DFN[maxn];int belong[maxn];bool  instack[maxn];vector<int> g[maxn];  //int Index=0;int bnt=0;int n,m;stack<int> st;void tarjan(int i){    DFN[i]=LOW[i]=++Index;    instack[i]=true;    st.push(i);    int len=g[i].size();    for(int j=0;j<len;j++){        // DFN[i] stands for the n-th that visited ,if DFN[i] is 0 means not visited;        if(!DFN[g[i][j]]){            tarjan(g[i][j]);            //LOW[i]=min(LOW[i],LOW[g[i][j]]);            if(LOW[i]>LOW[g[i][j]]) LOW[i]=LOW[g[i][j]];        }else if(instack[g[i][j]]&&LOW[i]>DFN[g[i][j]]){            LOW[i]=DFN[g[i][j]];        }    }    //    if(LOW[i]==DFN[i]){        bnt++;        int tmp;        while(st.top()!=i){            tmp=st.top();            belong[tmp]=bnt;            instack[tmp]=false;            st.pop();        }        if(st.top()==i){            st.pop();            belong[i]=bnt;            instack[i]=false;        }    }}bool solve(){    bnt=0;    Index=0;    //init    while(!st.empty())st.pop();    for(int i=0;i<=n;i++){        DFN[i]=0;        LOW[i]=0;        instack[i]=false;        belong[i]=0;    }    for(int i=1;i<=n;i++){        if(!DFN[i]){            tarjan(i);        }    }    //    if(bnt==1) return true;    else return false;}int main(){    int a,b;    while(scanf("%d%d",&n,&m)!=EOF){        if(n==0&&m==0) break;        for(int i=0;i<=n;i++) g[i].clear();        for(int i=0;i<m;i++){            scanf("%d%d",&a,&b);            g[a].push_back(b);        }        //solve to judge whether is strong connected graph or not        bool ans=false;        ans=solve();        if(ans)printf("Yes\n");        else printf("No\n");    }    return 0;}