• 旅游电车(tarjan算法+统计出度)


    旅游电车

    问题描述:
    Henryy国正致力于首都的一个旅游电车建设工程。首都有N个旅游景区。Henryy国的电车永远只沿道路规定的方向行驶,为了不使投入使用的电车有可能无法回到它的起始站,Henryy希望知道他的首都的可以在哪些景区设置站点。一个景区可以被设置成车站,当且仅当对于任意一个从该景区出发所能到达的景区,均至少有一条路可回到该景区。你的同事已完成了一份景区之间的道路连通情况的报告。报告中将给出首都的景区数目N、道路总数M以及一些形如“景区A和景区B之间有一条从A到B的单向道路”的信息。现在明确你的任务:根据报告中的信息,列出所有可以被设置成车站的景区。
    输入文件:
    输入文件由多份报告组成(这些报告相互无任何联系),每份报告包括:N,M,接下来M对整数Ai、Bi (1<=I<=M)表示Ai和Bi之间有一条单向道路Ai->Bi。仅一个包含整数N=0的报告表示你的工作结束,你的程序不应该对此有任何反应。各整数间用空格或空行分隔。对于任意景区,分别以该景区为起点或终点的道路总数均不超过50。
    输出文件:
    对于每份报告,输出一行列表包括:所有能被设置成电车站点的景区编号,各编号之间用一个空格隔开。
    样例输入:
    5 6
    1 2
    2 3
    3 4
    4 1
    2 5
    5 2
    1 0
    0
    样例输出:
    1 2 3 4 5
    1
    数据约定:
    对于40%的数据,有N<=200。
    对于100%的数据,有N<=5000,M<=50000。

    思路:
    tarjan算法+统计出度

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int maxn=50010;
    int n,m,tot,head[maxn];
    int top,b[maxn],out[maxn],s[maxn],stack[maxn],low[maxn],dfn[maxn];
    bool in[maxn];
    struct node
    {
        int to;
        int next;
    }e[maxn*2];
    void add_edge(int u,int v)
    {
        tot++;
        e[tot].to=v;
        e[tot].next=head[u];
        head[u]=tot;
    }
    void tarjan(int u)
    {
        int v;
        dfn[u]=low[u]=++tot;
        stack[++top]=u;
        in[u]=1;
        for(int i=head[u];i;i=e[i].next)
        {
            v=e[i].to;
            if(!dfn[v])
            {
                tarjan(v);
                low[u]=min(low[u],low[v]);
            }
            else if(in[v])
            low[u]=min(low[u],dfn[v]);
        }
        if(low[u]==dfn[u])
        {
            tot++;
            do
            {
                v=stack[top--];
                in[v]=0;
                b[v]=tot;
            }while(u!=v);
        }
    }
    int main()
    {
        int x,y;
        while(cin>>n&&n!=0)
        {
            memset(head,0,sizeof(head));
            memset(low,0,sizeof(low));
            memset(dfn,0,sizeof(dfn));
            memset(out,0,sizeof(out));
            memset(b,0,sizeof(b));  
            top=tot=0;
            cin>>m;
            for(int i=1;i<=m;i++)
            {
                cin>>x>>y;
                add_edge(x,y);
            }tot=0;
            for(int i=1;i<=n;i++)
            if(!dfn[i])
            tarjan(i);tot=0;
            for(int i=1;i<=n;i++)
              for(int j=head[i];j;j=e[j].next)
              if(b[i]!=b[e[j].to])
              out[b[i]]++;
            for(int i=1;i<=n;i++)
            if(!out[b[i]])
            s[++tot]=i;
            sort(s+1,s+tot+1);
            for(int i=1;i<=tot;i++)
            cout<<s[i]<<" ";
            cout<<endl;
        }
        return 0;
    }
  • 相关阅读:
    java几种字符串反转
    iOS安全攻防(三):使用Reveal分析他人app
    信息与计算科学
    搜索框中“请输入搜索keyword”
    上传图片图像进行压缩后上传
    ExtractFileDir 与 ExtractFilePath 的差别
    java中接口的定义与实现
    《IT运维之道》
    Linux查看硬件信息,主板型号及内存硬件,驱动设备,查看设备,查看CPU。
    CentOS6.5 x86_64 配置Broadcom 43XX系列 无线网卡驱动
  • 原文地址:https://www.cnblogs.com/cax1165/p/6070967.html
Copyright © 2020-2023  润新知