HDU-#1269 迷宫城堡(Tarjan+强连通)

来源:互联网 发布:社交推荐算法 编辑:程序博客网 时间:2024/05/21 15:11

题目大意:给一个有向图的关系,判断强连通分量有且只有一个。

解题思路:模板题,直接运用Tarjan算法进行求解,最后判断强连通分量是否为一。详见code。

题目来源:http://acm.hdu.edu.cn/showproblem.php?pid=1269

code:

#include <iostream>#include <cstdio>#include <cstring>#include <vector>#include <stack>#include <algorithm>using namespace std;const int MAXN = 10000+10;const int MAXM = 100000+10;vector<int> g[MAXN]; //存图int pre[MAXN],lowlink[MAXN],sccno[MAXM],dfs_clock,scc_cnt;stack<int> s;int n,m;void Tarjan(int u){    pre[u]=lowlink[u]=++dfs_clock; //时间戳++    s.push(u); //该点入栈    for(int i=0;i<g[u].size();i++){ //枚举每一条边        int v=g[u][i]; //邻接边        if(!pre[v]){ //未被访问            Tarjan(v);  //继续向下找            lowlink[u]=min(lowlink[u],lowlink[v]);//更新结点v所能到达的最下次数层        }        else if(!sccno[v]){//如果结点在栈内            lowlink[u]=min(lowlink[u],pre[v]);        }    }    if(lowlink[u]==pre[u]){ //如果结点u是强连通分量的根        scc_cnt++; //连通分量标号++        while(!s.empty()){            int x=s.top(); //取出栈顶元素            s.pop(); //弹出栈            sccno[x]=scc_cnt; //出栈结点x属于scc_cnt标号的强连通分量            if(x==u) break;        }    }}void solve(){    dfs_clock=scc_cnt=0; //初始化连通分量计数器和时间戳    memset(sccno,0,sizeof(sccno)); //初始化连通分量编号数组    memset(pre,0,sizeof(pre));  //深搜次序数组    for(int i=1;i<=n;i++) //遍历寻找连通分量        if(!pre[i]) Tarjan(i); //未被访问则找i结点的连通分量}int main(){    int u,v;    while(scanf("%d%d",&n,&m)!=EOF && (n||m)){        for(int i=1;i<=n;i++) g[i].clear(); //使用前清空        for(int i=1;i<=m;i++){  //读入图            scanf("%d%d",&u,&v);            g[u].push_back(v);        }        solve();        if(scc_cnt==1) printf("Yes\n");        else printf("No\n");    }    return 0;}


0 0
原创粉丝点击