危险系数

问题描述

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

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

我们来定义一个危险系数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

原文地址:https://www.cnblogs.com/mabeyTang/p/10453781.html