• poj2186


    题意:给出一个有向图,求一共有多少个点,满足这样的条件:所有其它的点都可以到达这个点。

    分析:强连通分支+缩点,然后统计每个强连通分支的出度,如果只有一个为0,则输出其内部点的个数,如果有多个为0,说明没有答案。

    View Code
    #include <iostream>
    #include
    <cstdlib>
    #include
    <cstring>
    #include
    <cstdio>
    usingnamespace std;

    #define maxn 10005
    #define maxm 50005

    struct Edge
    {
    int v, next;
    } edge[maxm], opedge[maxm];
    int n, m, head[maxn], ophead[maxn], ncount, nowtime, pos[maxn *2], sig[maxn], signnum, in[maxn];
    int pointnum[maxn];
    bool flag[maxn];
    void addedge(int a, int b)
    {
    edge[ncount].v
    = b;
    edge[ncount].next
    = head[a];
    head[a]
    = ncount;
    opedge[ncount].v
    = a;
    opedge[ncount].next
    = ophead[b];
    ophead[b]
    = ncount;
    ncount
    ++;
    }
    void input()
    {
    scanf(
    "%d%d", &n, &m);
    for (int i =0; i < m; i++)
    {
    int a, b;
    scanf(
    "%d%d", &a, &b);
    a
    --;
    b
    --;
    addedge(a, b);
    }
    }
    void dfs(int a)
    {
    flag[a]
    =true;
    pos[nowtime]
    = a;
    nowtime
    ++;
    for (int i = head[a]; i !=-1; i = edge[i].next)
    if (!flag[edge[i].v])
    dfs(edge[i].v);
    pos[nowtime]
    = a;
    nowtime
    ++;
    }
    void rdfs(int a)
    {
    flag[a]
    =true;
    sig[a]
    = signnum;
    pointnum[sig[a]]
    ++;
    for (int i = ophead[a]; i !=-1; i = opedge[i].next)
    if (!flag[opedge[i].v])
    rdfs(opedge[i].v);
    }

    int main()
    {
    //freopen("t.txt", "r", stdin);
    ncount =0;
    memset(head,
    -1, sizeof(head));
    memset(ophead,
    -1, sizeof(ophead));
    memset(flag,
    0, sizeof(flag));
    input();
    nowtime
    =1;
    for (int i =0; i < n; i++)
    if (!flag[i])
    dfs(i);
    memset(flag,
    0, sizeof(flag));
    memset(pointnum,
    0, sizeof(pointnum));
    signnum
    =0;
    for (int i =2* n; i >0; i--)
    if (!flag[pos[i]])
    {
    rdfs(pos[i]);
    signnum
    ++;
    }
    memset(
    in, 0, sizeof(in));
    ncount
    =0;
    for (int i =0; i < n; i++)
    for (int j = head[i]; j !=-1; j = edge[j].next)
    if (sig[i] != sig[edge[j].v])
    in[sig[i]]++;
    int ans =-1;
    bool ok =true;
    for (int i =0; i < signnum; i++)
    if (in[i] ==0)
    {
    if (ans !=-1)
    {
    ok
    =false;
    break;
    }
    ans
    = i;
    }
    if (ok)
    printf(
    "%d\n", pointnum[ans]);
    else
    printf(
    "0\n");
    return0;
    }
  • 相关阅读:
    小熊派4G开发板初体验
    空间换时间,查表法的经典例子
    C语言、嵌入式应用:TCP通信实践
    【实践】基于RT-Thread的智慧路灯案例实验分享
    STM32串口打印的那些知识
    【RT-Thread笔记】BH1750软件包的使用
    【RT-Thread笔记】OneNet软件包的使用
    串口通讯你真的会了吗?不妨看看这些经验
    三小记(2)
    audio标签实现简单的自定义播放器
  • 原文地址:https://www.cnblogs.com/rainydays/p/2072950.html
Copyright © 2020-2023  润新知