• PAT甲题 1013 Battle Over Cities


    PAT甲题 1013 Battle Over Cities


    刚读完这题有点懵,准确的说是数据结构没好好学的我有点心虚,不知如何下手,翻出教材把求割点的算法仔细读了一下,没啥帮助,后来顿悟,其实这题只需要无脑dfs就可以了。

    题意回顾:

    在战争中,使自己的所有领地(拥有的城市)保持连通是很重要的,所谓保持连通即城市之间有公路连接,画成图模型即此图为连通图。但是战争中自己的某个城市很有可能被敌方占领,这就可能使我们本来连通的图变的不连通,于是我们就得修建公路使我们剩下的城市之间再次组成连通图。
    输入规格:
    1.第一行包含三个正整数,N,M,K,其中N<1000,它们分别代表你拥有的城市数,现有公路数,和你需要检查的公路数。我们以1到N对城市进行标号。接下来有M行输入,每行有两个城市号,意味着这两个城市之间有一条公路连通。最后一行有K个整数,每一个代表我们需要检查的城市号。
    输出规格:
    依次输出需要检查的城市如果沦陷我们需要建的公路数,每个输出占一行。

    个人思路:

    1.用邻接矩阵或者邻接表来存储城市间的道路信息,我偷懒用了邻接矩阵,打算超时再改邻接表,实际上道路并不会很多,所以这种稀疏矩阵用链表来写效率会高得多;
    2.用dfs来进行遍历,每次挑选未遍历过的非此次沦陷的城市,直到除了沦陷城市所有城市都被遍历过。设遍历次数为n,撇开沦陷的城市不看,此时有n个连通图(也有可能有的是孤立结点),则我们需建n-1条路;
    3.用map存储某个结点是否被遍历过,关键字为城市号,值为是否被遍历过(bool);
    4.个人觉得此题没什么坑点,掌握好算法,别超时就好。

    代码:

    #include<iostream>
    #include<map>
    using namespace std;
    int N, M, K, a, b, hs = 0;  //hs存储已经遍历过的结点数
    int adj[1000][1000] = {};   //邻接矩阵
    map<int, bool> mp;
    void dfs(int v, int w)  //递归深搜
    {
     mp[v] = true;
     hs++;
     for (int i = 1; i <= N; i++)
     	 if (adj[i][v] && !mp[i] && i != w)
      		 dfs(i, w);
    }
    int Number(int w)
    {
     int count = -1;
     for (int i = 1; hs != N - 1; i++)
    	  if (!mp[i] && i != w) //不能以沦陷的城市为起点进行深搜
     	 {
      		 dfs(i, w);
      		 count++;
     	 } 
     hs = 0;  
     mp.clear();  //记得把hs和mp都还原
     return count;
    }
    int main()
    {
     cin >> N >> M >> K;
     for (int i = 0; i < M; i++)
     {
     	 cin >> a >> b;
     	 adj[a][b] = adj[b][a] = 1;
     }
     for (int i = 0; i < K; i++)
     {
    	  cin >> a;
    	  cout << Number(a) << endl;
     }
     return 0;
    }

    这边的算法效率还是可以继续优化的,思路之一就是使用邻接表,我多提交了几次发现有时候最后一个测试点是会超时的,没有超时也在350ms+,所以还是在扣分边缘徘徊。。

  • 相关阅读:
    Python的简单介绍/解释器/变量/变量的数据类型/用户交互及流程控制(if)
    变量
    hello python
    页面默认值显示
    java 获取时间区间
    java Set 中 removeAll 与 addAll
    命名的数据库实例
    linux 打包与解包
    缓存工作原理
    java 格式化日期(转)
  • 原文地址:https://www.cnblogs.com/yuhan-blog/p/12309118.html
Copyright © 2020-2023  润新知