杭电1269--迷宫城堡(强连通分量)

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

连通分量, 断断续续看了几天, 今天终于A了道强联通分量(SCC)模板题。 初学SCC, 理解的还不是很好, 是利用Dfs中回溯过程进行操作, 细节掌握还不够好。

本题题意是判断有向图中SCC 个数是否唯一, 模板题;

#include <stack>
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;

const int N = 10001;

struct Edge
{
    int from, to, next;
} edge[100100];

int n, m, cnt, cnt_SCC, vis_num, low[N], tim[N], head[N], instack[N];
void Add(int a, int b)
{
    Edge E = {a, b, head[a]};
    edge[cnt] = E;
    head[a] = cnt++;    
}

stack <int>S;
void TarJan(int x)
{
    int j;
    tim[x] = low[x] = ++vis_num;
    instack[x] = 1;
    S.push(x);
    for(int i = head[x]; i != -1; i = edge[i].next)
    {
        int u = edge[i].to;
        if(tim[u] == -1)
        {
            TarJan(u);
            if(low[x] > low[u])
                low[x] = low[u];
        }
        else if(instack[u] && low[x] > tim[u])
            low[x] = tim[u];
    }
    if(low[x] == tim[x])
    {
        cnt_SCC++;
        do{
            j = S.top();
            S.pop();
            instack[j] = 0; 
        } while(j != x);
    }     
}

void Solve()
{
    vis_num = cnt_SCC = 0; 
    for(int i = 1; i <= n; i++)
        if(tim[i] == -1)
            TarJan(i);
    if(cnt_SCC == 1)
        puts("Yes");
    else
        puts("No");
}

void GetMap()
{
    int a, b;
    memset(instack, 0, sizeof(instack));
    memset(low, 0, sizeof(low));
    memset(tim, -1, sizeof(tim));
    
    cnt = 0;
    memset(head, -1, sizeof(head));
    while(m--)
    {
        scanf("%d%d", &a, &b);
        Add(a, b);
    }
}

int main()
{
    while(~scanf("%d%d", &n, &m), n+m)
    {
        GetMap();
        Solve();
    }
    return 0;  }

MyGod

1 大神解析(SCC_TarJan):
2 http://blog.sina.com.cn/s/blog_7a1746820100vtk9.html
3 http://www.cnblogs.com/saltless/archive/2010/11/08/1871430.html

贴个并查集做法, 并查集有点好用。 两个并查集,一个反向处理有向边。

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
int father[3][10001];

int find(int a, int i)
{
    if(father[i][a] == a)
        return a;
    else
        return find(father[i][a], i);
}

int n, m;
void mercy(int a , int b)
{
    int P, Q; 
    if(a != n)                //Important; 
    {
        P = find(a, 0);
        Q = find(b, 0);
        if(P != Q)
            father[0][a] = b;  // Detail;
    }    
    if(b != n)
    {
        P = find(a, 1);
        Q = find(b, 1);
        if(P != Q)
            father[1][b] = a;  
    }
}

int main()
{
    while(~scanf("%d%d", &n, &m), n+m)
    {
        for(int i = 1; i <= n; i++)
            father[0][i] = father[1][i] = i;
        for(int i = 1; i <= m; i++)
        {
            int a, b;
            scanf("%d%d", &a, &b);
            mercy(a, b);    
        }
        bool flag = true;
        for(int i = 1; i <= n; i++)
        {
            if(find(i, 0) != n || find(i, 1) != n)    
            {
                flag = false;
                break; 
            }
        }
        if(flag)
            printf("Yes\n"); 
        else
            printf("No\n");
    } 
    return 0;
}

时间: 2024-10-09 05:13:36

杭电1269--迷宫城堡(强连通分量)的相关文章

hdu 1269 迷宫城堡 强连通分量

迷宫城堡 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 12778    Accepted Submission(s): 5698 Problem Description 为了训练小希的方向感,Gardon建立了一座大城堡,里面有N个房间(N<=10000)和M条通道(M<=100000),每个通道都是单向的,就是说若称某通道连通了A

hdoj 1269 迷宫城堡(强连通分量)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1269 思路分析:该问题要求判断是否每两个房间都可以相互到达,即求该有向图中的所有点是否只构成一个强连通图分量,使用Tarjan算法即可求解: 代码如下: #include <stack> #include <vector> #include <cstdio> #include <cstring> #include <iostream> using n

HDU_1269_迷宫城堡(强连通分量)

迷宫城堡 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 8872    Accepted Submission(s): 3987 Problem Description 为了训练小希的方向感,Gardon建立了一座大城堡,里面有N个房间(N<=10000)和M条通道(M<=100000),每个通道都是单向的,就是说若称某通道连通了A

迷宫城堡 强连通分量(scc-tarjan)

迷宫城堡 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 12923    Accepted Submission(s): 5777 Problem Description 为 了训练小希的方向感,Gardon建立了一座大城堡,里面有N个房间(N<=10000)和M条通道(M<=100000),每个通道都是单 向的,就是说若称某通道连通

hdu - 1269 迷宫城堡 (强连通裸题)

http://acm.hdu.edu.cn/showproblem.php?pid=1269 判断一个图是不是强连通,缩点之后判断顶点数是不是为1即可. 1 #include <iostream> 2 #include <cstdio> 3 #include <cmath> 4 #include <vector> 5 #include <cstring> 6 #include <algorithm> 7 #include <st

杭电ACM1269——迷宫城堡~~并查集

这题,可以用并查集来解决.需要用到两个数组来判断从i到j以及j到i的是否属于同一个并查集. 下面的是AC的代码: #include <iostream> #include <cstdio> using namespace std; int par[2][10005]; int n, m; int finds(int x, int i) { if(x == par[i][x]) return x; else return par[i][x] = finds(par[i][x], i)

HDU 1269 迷宫城堡(强连通)

HDU 1269 迷宫城堡 题目链接 题意:中文题 思路:强连通模板题 代码: #include <cstdio> #include <cstring> #include <vector> #include <stack> using namespace std; const int N = 10005; int n, m; vector<int> g[N], scc[N]; int pre[N], lowlink[N], sccno[N], d

hdu 1269 迷宫城堡 (tarjan算法学习)

迷宫城堡 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 7056    Accepted Submission(s): 3137 Problem Description 为了训练小希的方向感,Gardon建立了一座大城堡,里面有N个房间(N<=10000)和M条通道(M<=100000),每个通道都是单向的,就是说若称某通道连通了A

hdu 1269 迷宫城堡

迷宫城堡 Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other) Total Submission(s) : 29   Accepted Submission(s) : 12 Font: Times New Roman | Verdana | Georgia Font Size: ← → Problem Description 为了训练小希的方向感,Gardon建立了一座大城堡,里面有N个房