zoukankan      html  css  js  c++  java
  • 高速公路

    试题编号: 201509-4
    试题名称: 高速公路
    时间限制: 1.0s
    内存限制: 256.0MB
    问题描述:
    问题描述
      某国有n个城市,为了使得城市间的交通更便利,该国国王打算在城市之间修一些高速公路,由于经费限制,国王打算第一阶段先在部分城市之间修一些单向的高速公路。
      现在,大臣们帮国王拟了一个修高速公路的计划。看了计划后,国王发现,有些城市之间可以通过高速公路直接(不经过其他城市)或间接(经过一个或多个其他城市)到达,而有的却不能。如果城市A可以通过高速公路到达城市B,而且城市B也可以通过高速公路到达城市A,则这两个城市被称为便利城市对。
      国王想知道,在大臣们给他的计划中,有多少个便利城市对。
    输入格式
      输入的第一行包含两个整数n, m,分别表示城市和单向高速公路的数量。
      接下来m行,每行两个整数a, b,表示城市a有一条单向的高速公路连向城市b。
    输出格式
      输出一行,包含一个整数,表示便利城市对的数量。
    样例输入
    5 5
    1 2
    2 3
    3 4
    4 2
    3 5
    样例输出
    3
    样例说明

      城市间的连接如图所示。有3个便利城市对,它们分别是(2, 3), (2, 4), (3, 4),请注意(2, 3)和(3, 2)看成同一个便利城市对。
    评测用例规模与约定
      前30%的评测用例满足1 ≤ n ≤ 100, 1 ≤ m ≤ 1000;
      前60%的评测用例满足1 ≤ n ≤ 1000, 1 ≤ m ≤ 10000;
      所有评测用例满足1 ≤ n ≤ 10000, 1 ≤ m ≤ 100000。

     分析:

    本题考察的是求有向图中强连通分量的应用,该题采用的是tarjan算法,关于tarjan算法可以阅读tarjan算法-解决有向图中求强连通分量的利器这篇文章。

    不多说,上代码:

    #include "Stdafx.h"
    #include <iostream>
    #include <stack>
    using namespace std;
    
    #define MAX_VERTEX_SIZE 10001
    struct EdgeNode{
        int vertex;
        EdgeNode *nextArc;
    };
    
    struct VerTexNode{
        EdgeNode* firstArc;
    };
    
    struct Graph{
        int n,e;
        VerTexNode vNode[MAX_VERTEX_SIZE];
    };
    
    int time = 0;
    int low[MAX_VERTEX_SIZE];
    int dfn[MAX_VERTEX_SIZE];
    int visited[MAX_VERTEX_SIZE];
    int inStack[MAX_VERTEX_SIZE];
    int ans = 0;//存储运算结果
    stack<int> st;
    Graph graph;
    
    void initeGraph(int n,int m)
    {
        for(int i = 1;i<=n;i++)
        {
            graph.vNode[i].firstArc = NULL;
        }
        graph.n = n;
        graph.e = m;
    
    }
    
    //头插法建立图
    void creatGraph(int s,int v)
    {
        EdgeNode *edgeNode = new EdgeNode;
        edgeNode->vertex = v;
        edgeNode->nextArc = graph.vNode[s].firstArc;
        graph.vNode[s].firstArc = edgeNode;
    }    
    
    int min(int a,int b)
    {
        if(a>b)
            return b;
        else
            return a;
    }
    
    void trajan(int u)
    {
        dfn[u] = low[u] = time++;
        st.push(u);
        visited[u] = 1;
        inStack[u] = 1;
        EdgeNode *edgePtr = graph.vNode[u].firstArc;
        while(edgePtr !=NULL)
        {
            int v = edgePtr->vertex;
            if(visited[v] == 0)
            {
                trajan(v);
                low[u] = min(low[u],low[v]);
            }
            /*之前没有对inStack[v]进行判断,又可能当前的v已经出栈了,这个时候就会出错。
            所以导致我的最后得分为80分。
            加上if条件,最后为满分。
            切记!切记!切记!!!
            */
    
            else if(inStack[v] == 1)
            {
                low[u] = min(low[u],dfn[v]);
            }
            edgePtr = edgePtr->nextArc;
        }
    
        int result = 0;
        if(dfn[u] == low[u])
        {
            int vtx;
            //cout<<"set is: ";
            do{
                result++;
                vtx = st.top();
                st.pop();
                inStack[vtx] = 0;//表示已经出栈
            /*    cout<<vtx<<' ';*/
            }while(vtx !=u );
            if(result > 1)
            {
                ans += result*(result-1)/2;
            }
            result = 0;
        }
    
    }
    
    int main()
    {
        int n,m;
        int s,a;
        cin>>n>>m;
        initeGraph(n,m);
        for(int i = 1;i<=n;i++)
        {
            visited[i] = 0;
            inStack[i] = 0;
            dfn[i] = 0;
            low[i] = 0;
        }
    
        for(int j = 1;j<=m;j++)
        {
            cin>>s>>a;
            creatGraph(s,a);
        }
    
        for(int i =1;i<=n;i++)
            if(visited[i] == 0)
                trajan(i);
        cout<<ans<<endl;
        return 0;
    }
    View Code
  • 相关阅读:
    发布国内首个无服务器容器服务,运维效率从未如此高效
    阿里云异构计算团队亮相英伟达2018 GTC大会
    阿里如何将“高峰前扩容、高峰后缩容”的梦想照进现实?
    迁移到 GRUB 2
    (11计科1班-孙鹏启)SHELL脚本—期末成绩统计
    硬盘分区的c盘在外圈还是内圈
    Linux内核设计的艺术(第2版)
    卸载,弹出,安全移除驱动器 的区别
    (11级计科2班-张文旭)关于LINUX连接网络问题
    安装Zend Guard Loader
  • 原文地址:https://www.cnblogs.com/tgycoder/p/5049227.html
Copyright © 2011-2022 走看看