zoukankan      html  css  js  c++  java
  • 危险系数

    问题描述

    抗日战争时期,冀中平原的地道战曾发挥重要作用。

    地道的多个站点间有通道连接,形成了庞大的网络。但也有隐患,当敌人发现了某个站点后,其它站点间可能因此会失去联系。

    我们来定义一个危险系数DF(x,y):

    对于两个站点x和y (x != y), 如果能找到一个站点z,当z被敌人破坏后,x和y不连通,那么我们称z为关于x,y的关键点。相应的,对于任意一对站点x和y,危险系数DF(x,y)就表示为这两点之间的关键点个数。

    本题的任务是:已知网络结构,求两站点之间的危险系数。

    输入格式

    输入数据第一行包含2个整数n(2 <= n <= 1000), m(0 <= m <= 2000),分别代表站点数,通道数;

    接下来m行,每行两个整数 u,v (1 <= u, v <= n; u != v)代表一条通道;

    最后1行,两个数u,v,代表询问两点之间的危险系数DF(u, v)。

    输出格式
    一个整数,如果询问的两点不连通则输出-1.
    样例输入
    7 6
    1 3
    2 3
    3 4
    3 5
    4 5
    5 6
    1 6
    样例输出
    2

    Algorithm

    最开始想到图的割点的计算,就去学习Tarjan算法。但是后来发现,该算法是求所有的割点,但是这个题目我们是求起点到终点之间路径的割点数。因此,我们还要将所有的路径遍历出来。

    最后终于看到了一个比较人性化的思路:遍历出起点到终点之间的所有路线,然后找出每条路径都会经历的点(除开起点与终点)!那么这些点就是割点。

    此外,还可以使用并查集,如果起点与终点不连通,那么就不在一个集合,输出-1。


    AC

      1 /*
      2 * Tarjan算法
      3 * DFS 
      4 */
      5 #include<iostream>
      6 #include<vector> 
      7 #include<algorithm>
      8 #include<stdio.h>
      9 #include<cstring>
     10 
     11 using namespace std;
     12 
     13 const int MAXN = 1<<10;
     14 
     15 vector<int> v[MAXN], path;
     16 bool book[MAXN];
     17 vector<int> P[99];
     18 int k = 0;
     19 int dic[MAXN];
     20 
     21 void DFS(int x, int y)
     22 {    
     23     if(x == y){
     24         for(int i=0;i<path.size();i++){
     25             dic[path.at(i)]++;
     26         }
     27         k++;
     28     }
     29     else{
     30         for(int i=0;i<v[x].size();i++){
     31             int t = v[x].at(i);
     32             if(book[t])
     33                 continue;
     34             book[t] = true;
     35             path.push_back(t);
     36             DFS(t, y);
     37             path.erase(path.end()-1);
     38             book[t] = false;
     39         } 
     40     }
     41 }
     42 
     43 int main()
     44 {
     45     int m, n;
     46     while(cin>>m>>n)
     47     {
     48         int x, y;
     49         memset(book, false, sizeof(book));
     50         memset(dic, 0, sizeof(dic));
     51         while(n--)
     52         {
     53             scanf("%d%d", &x, &y);
     54             v[x].push_back(y);
     55             v[y].push_back(x);
     56         }
     57         cin>>x>>y;
     58         path.push_back(x);
     59         DFS(x, y);
     60         // cout<<"K"<<k<<'
    ';
     61         // 之前忘了判断不连通的情况 
     62         if(k == 0){
     63             cout<<-1<<'
    ';
     64             continue;
     65         }
     66         int ans = 0;
     67         for(int i=1;i<=m;i++)
     68             if(dic[i] == k) ans++;
     69         cout<<(ans-2)<<'
    ';
     70     }
     71     
     72     return 0;
     73 }
     74 /*--------------------------------------*/
     75 /*
     76 
     77 memset(dfn, 0, sizeof(dfn));
     78 memset(low, 0, sizeof(low));
     79 memset(par, 0, sizeof(par));
     80 */
     81 
     82 /*
     83 // 下标顶点编号
     84 // 值表示该顶点在DFS中的遍历顺序
     85 int low[MAXN];
     86 // 值表示DFS中该顶点不通过父顶点能访问到的祖先顶点中最小的顺序值     
     87 int dfn[MAXN];
     88 // 值表示该顶点的父顶点编号
     89 int par[MAXN];
     90 // 顶点是否访问过
     91 
     92 // Tarjan算法
     93 void Tarjan(int x)
     94 {
     95     book[x] = true;
     96     for(int i=0;i<v[x].size();i++){
     97         book[v[x].at(i)] = true;
     98         Tarjan(a[x].at(i));
     99     }
    100     
    101     return;
    102 }
    103 */
    View Code

    2019-02-28

    22:52:12

  • 相关阅读:
    程序的编码问题
    man DMIDECODE
    Github熟悉一
    man uname
    第一轮铁大树洞APP开发冲刺(2)
    第九周学习进度
    第九周安卓开发学习总结(3)
    第一轮铁大树洞APP开发冲刺(1)
    第九周安卓开发学习总结(2)
    第九周安卓开发学习总结(1)
  • 原文地址:https://www.cnblogs.com/mabeyTang/p/10453781.html
Copyright © 2011-2022 走看看