• [poj][2553][The Bottom of a Graph]


    题目:http://poj.org/problem?id=2553

    题意:一张有向图G,G图中从v可达的所有点w,也都可以达到v,这样的v称为sink。按照大小全部输出,没有输出空行。

    方法:tarjan

    View Code
    #include <stdio.h>
    #include <string.h>
    #include <math.h>
    #include <algorithm>

    #define Max(A,B) ((A)>(B)?(A):(B))
    #define Min(A,B) ((A)<(B)?(A):(B))
    #define clr(a,b) memset(a, b, sizeof(a))
    using namespace std;

    const int MAXV = 10000+10;
    const int inf = 0x3f3f3f3f;

    const int N = 10010;
    const int M = 50010;
    int e, ev[M], nxt[M], head[N];
    bool instack[N];
    int dfn[N], low[N], dindex, q[N], ed;
    int belong[N], bcnt;
    int n, m;
    bool out[N];
    int ans[N];
    int initout[N];
    void addedge(int u, int v)
    {
    ev[e] = v; nxt[e] = head[u]; head[u] = e++;
    }

    void tarjan(int u)
    {
    int i, v;
    dfn[u] = low[u] = ++dindex;
    instack[u] = 1;
    q[ed++] = u;
    for (i = head[u]; ~i; i = nxt[i])
    {
    v = ev[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])
    {
    do{
    belong[v = q[--ed]] = bcnt;
    instack[v] = 0;
    }while (v != u);
    bcnt++;
    }
    }

    void solve()
    {
    ed = bcnt = dindex = 0;
    clr(dfn, 0); clr(instack, 0);
    for (int i=0; i<n; i++)
    if (!dfn[i]) tarjan(i);
    }

    int main()
    {
    //freopen("D:/a.txt", "r", stdin);
    while (~scanf("%d", &n) && n)
    {
    e = 0;
    clr(head, -1);
    clr(initout, 0);
    scanf("%d", &m);
    for (int i=0; i<m; i++)
    {
    int u, v;
    scanf("%d%d", &u, &v);
    addedge(u-1, v-1);
    initout[u-1]++;
    }
    solve();

    clr(out, 0);
    for (int i=0; i<n; i++)
    {
    for (int j=head[i]; ~j; j=nxt[j])
    {
    if (belong[i] != belong[ev[j]])
    {
    out[belong[i]] = true;
    }
    }
    }
    int t = 0;
    for (int i=0; i<n; i++)
    {
    if (initout[i]==0) {ans[t++] = i+1; continue;}
    if (!out[belong[i]]) ans[t++] = i+1;
    }
    printf("%d", ans[0]);
    for (int i=1; i<t; i++) {
    printf(" %d", ans[i]);
    }
    puts("");
    }
    }
  • 相关阅读:
    Python入门11 —— 基本数据类型的操作
    Win10安装7 —— 系统的优化
    Win10安装6 —— 系统的激活
    Win10安装5 —— 系统安装步骤
    Win10安装4 —— 通过BIOS进入PE
    Win10安装2 —— 版本的选择与下载
    Win10安装1 —— 引言与目录
    Win10安装3 —— U盘启动工具安装
    虚拟机 —— VMware Workstation15安装教程
    Python入门10 —— for循环
  • 原文地址:https://www.cnblogs.com/nigel0913/p/2434808.html
Copyright © 2020-2023  润新知