zoukankan      html  css  js  c++  java
  • HDU-1269 Tarjan求强连通分量,模板题

    HDU 1269

    题意:n个点m条单向边,问任意两个点是否连通。

    总结:参考大神博客码的,有些地方还是不太明白。 而且这题还可以双向dfs做,有时间再做一下。

    // HDU-1269 
    #include<bits/stdc++.h>
    using namespace std;
    #pragma comment(linker, "/STACK:102400000,102400000")
    #define F(i,a,b)  for (int i=a;i<b;i++)
    #define FF(i,a,b) for (int i=a;i<=b;i++)
    #define mes(a,b)  memset(a,b,sizeof(a))
    #define INF 0x3f3f3f3f
    typedef long long ll;
    const int N = 1e4+10, M = 1e5+10;
    
    int n, m, sum, top, tot;    //sum为强连通分量数,top为栈指针
    int head[N], Stack[N], instack[N];  //Stack[]为模拟栈,instack[]表示是否在栈中
    int dfn[N], low[N], Belong[N];     
    //dfn[]为深搜次序数组,Low[u]为u结点或者u的子树结点所能追溯到的最早栈中结点的次序号,这两个数组是关键。Belong[]表示每个结点所对应的强连通分量标号数组,这个题里用不到
    struct Edge { int to, next; } edge[M];
    
    void Init()
    {
        sum=top=tot=0;
        mes(head, -1);
        mes(dfn, 0);
    }
    void Addedge(int u, int v)
    {
        edge[tot].to=v;
        edge[tot].next=head[u];
        head[u]=tot++;
    }
    void Tarjan(int u)      //Tarjan算法求有向图的强连通分量   
    {
        dfn[u]=low[u]=++tot;  //时间戳,不太明白
        Stack[top++]=u, instack[u]=1;
        for(int e=head[u]; e!=-1; e=edge[e].next) {
            int v=edge[e].to;
            if(dfn[v]==0) {
                Tarjan(v);
                if(low[u]>low[v]) low[u]=low[v];  //更新结点v所能到达的最小次数层,这里不太明白
            }
            else if(instack[v] && low[u]>dfn[v]) {
                low[u]=dfn[v];
            }
        }
        if(dfn[u]==low[u]) {  //如果节点v是强连通分量的根   
            sum++;
            while(top!=0) {
                int t=Stack[--top];
                instack[t]=0;
                Belong[t]=sum;
                if(t==u) break; //直到将v从栈中退出,这不太明白
            }
        }
    }
    void Solve()
    {
        FF(i,1,n) if(dfn[i]==0)
            Tarjan(i);
    }
    int main()
    {
        while(scanf("%d%d", &n, &m)!=EOF && (n||m)) {
            Init();
            FF(i,1,m) {
                int u, v;
                scanf("%d%d", &u, &v);
                Addedge(u, v);
            }
            Solve();
            if(sum==1) puts("Yes");
            else puts("No");
        }
    
        return 0;
    }
    Tarjan求强连通
  • 相关阅读:
    汉英单词对照,汉英部分
    解密SQL Server存储过程等对象
    统计信息对执行计划的影响(二)
    统计信息对执行计划的影响(一)
    asp.net 避免 ajax 定时调用,利用 ashx 实现 long polling (长轮询)
    [ADO.NET][Command]如何抓取第一筆資料的第一個欄位或scalar值?
    鱼骨图
    js 中跳出多层循环
    IIS无法 添加/编辑 应用程序扩展名映射的原因
    如何让域名后面不显示xxx.do后缀
  • 原文地址:https://www.cnblogs.com/sbfhy/p/6349736.html
Copyright © 2011-2022 走看看