蓝桥--危险系数(求两点之间的割点个数)
历届试题 危险系数
时间限制:1.0s 内存限制:256.0MB
问题描述
抗日战争时期,冀中平原的地道战曾发挥重要作用。
地道的多个站点间有通道连接,形成了庞大的网络。但也有隐患,当敌人发现了某个站点后,其它站点间可能因此会失去联系。
我们来定义一个危险系数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
1 3
2 3
3 4
3 5
4 5
5 6
1 6
样例输出
2
分析:没思路看了题解=_=...
大神是这样说的:遍历s到t的所有路径,假设有ans条路径,对于割点a来说,在这ans条路径上都有a,所以a才成为了割点。
这里用了链表结构用来存图,都不记得怎么用了=_=...
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 using namespace std; 5 const int N = 1000 + 10; 6 const int M = 2000 + 10; 7 struct node 8 { 9 int to, Next; 10 }; 11 node edge[M]; 12 int n, m; 13 int cnt[N], way[N], vis[N]; 14 int tot, ans; 15 int head[N]; 16 void add(int u, int v) 17 { 18 edge[tot].to = v; 19 edge[tot].Next = head[u]; 20 head[u] = tot++; 21 } 22 void dfs(int x, int t, int n) 23 { 24 if(x == t) 25 { 26 ans++; 27 for(int i = 0; i < n; i++) 28 cnt[way[i]]++; 29 return ; 30 } 31 for(int u = head[x]; u != -1; u = edge[u].Next) 32 { 33 int v = edge[u].to; 34 if(!vis[v]) 35 { 36 vis[v] = 1; 37 way[n] = v; 38 dfs(v, t, n + 1); 39 vis[v] = 0; 40 } 41 } 42 } 43 int fun() 44 { 45 int ret = 0; 46 for(int i = 1; i <= n; i++) 47 if(cnt[i] == ans) 48 ret++; 49 return ret; 50 } 51 int main(int argc, char** argv) 52 { 53 scanf("%d%d", &n, &m); 54 memset(cnt, 0, sizeof(cnt)); 55 memset(way, 0, sizeof(way)); 56 memset(head, -1, sizeof(head)); 57 memset(vis, 0, sizeof(vis)); 58 tot = ans = 0; 59 for(int i = 0; i < m; i++) 60 { 61 int a,b; 62 scanf("%d%d", &a, &b); 63 add(a, b); 64 add(b, a); 65 } 66 int s, t; 67 scanf("%d%d", &s, &t); 68 vis[s] = 1; 69 dfs(s, t, 0); 70 printf("%d\n", fun() - 1); // 因为多算了个t 71 return 0; 72 }