割点与割边问题
2015-08-24 10:51
423 查看
连通性一·割边与割点
题目传送:hihoCoder - 1183 - 连通性一·割边与割点AC代码:
[code]#include <map> #include <set> #include <list> #include <cmath> #include <deque> #include <queue> #include <stack> #include <bitset> #include <cctype> #include <cstdio> #include <string> #include <vector> #include <complex> #include <cstdlib> #include <cstring> #include <fstream> #include <sstream> #include <utility> #include <iostream> #include <algorithm> #include <functional> #define LL long long #define INF 0x7fffffff using namespace std; const int maxn = 20005; int n, m; vector<int> G[maxn]; int dfn[maxn];//用于标记访问次序 int low[maxn];//low[u]为u及其后代所能连回的最早的祖先的dfn值 int vis[maxn];//标记 int pa[maxn];//记录父亲结点 int is_cut[maxn];//记录是否为割点 struct node { int u, v; }ans_b[200005]; int ans_bian; bool cmp(node a, node b) { if(a.u == b.u)return a.v < b.v; return a.u < b.u; } int cur_index; void dfs(int u) { dfn[u] = low[u] = ++ cur_index; vis[u] = 1; int child = 0; int d = G[u].size(); for(int i = 0; i < d; i ++) { int v = G[u][i]; if(!vis[v]) { child ++; pa[v] = u; dfs(v); low[u] = min(low[u], low[v]); if(pa[u] == 0 && child > 1) { is_cut[u] = 1;//这里的割点不能存在一个数组里,如果硬要存的话,则需要判重 } if(pa[u] != 0 && low[v] >= dfn[u]) { is_cut[u] = 1; } if(low[v] > dfn[u]) {//而割边的话可以用数组存,因为边只访问一次,不会重复,而点可能访问多次 ans_b[ans_bian].u = min(u, v); ans_b[ans_bian].v = max(u, v); ans_bian ++; } } else if(v != pa[u]){ low[u] = min(dfn[v], low[u]); } } } int main() { scanf("%d %d", &n, &m); int u, v; for(int i = 0; i < m; i ++) { scanf("%d %d", &u, &v); G[u].push_back(v); G[v].push_back(u); } cur_index = 0; ans_bian = 0; memset(pa, 0, sizeof(pa)); memset(vis, 0, sizeof(vis)); dfs(1); //for(int i = 1; i <= n; i ++) cout << low[i] << " "; cout << endl; int flag = 0; for(int i = 1; i <= n; i ++) if(is_cut[i]){ if(flag) printf(" "); flag = 1; printf("%d", i); } if(!flag) printf("Null"); printf("\n"); //cout << "haha" << endl; sort(ans_b, ans_b + ans_bian, cmp); for(int i = 0; i < ans_bian; i ++) { printf("%d %d\n", ans_b[i].u, ans_b[i].v); } return 0; }
危险系数
题目传送:蓝桥杯 - 历届试题 危险系数题目大意:去求有多少个点,使得去掉这个点之后,U,V不再连通。
分析:类似割点,这里因为数据量较小,可以暴力标记所有从U到V的路径,然后给每一个点记录一个权值,权值的含义为这个点在多少条从U到V的路径上,同时用cnt记录有多少条从U到V的路径,最后只要某个点的权值等于cnt的话,说明这个点就是U和V的割点,因为它在从U到V的所有路径上。
注意:还有不连通的情况要特判一下,即cnt=0的时候
AC代码:
[code]#include <map> #include <set> #include <list> #include <cmath> #include <deque> #include <queue> #include <stack> #include <bitset> #include <cctype> #include <cstdio> #include <string> #include <vector> #include <complex> #include <cstdlib> #include <cstring> #include <fstream> #include <sstream> #include <utility> #include <iostream> #include <algorithm> #include <functional> #define LL long long #define INF 0x7fffffff using namespace std; const int maxn = 1005; int n, m; vector<int> G[maxn];//整个图 int way[maxn];//记录每一条路的各个结点 int sum[maxn];//记录每个节点在多少条从U到V的路径上 int vis[maxn];//标记数组 int U, V; int cnt;//用于记录从U到V的路径的个数 void dfs(int u, int n) {//深搜找所有路径 way = u; if(u == V) {//找到一条路径,并return cnt ++; for(int i = 0; i <= n; i ++) { sum[way[i]] ++; } } int d = G[u].size(); for(int i = 0; i < d; i ++) { int v = G[u][i]; if(!vis[v]) { vis[v] = 1; dfs(v, n + 1); vis[v] = 0; } } } int main() { scanf("%d %d", &n, &m); int u, v; for(int i = 0; i < m; i ++) { scanf("%d %d", &u, &v); G[u].push_back(v); G[v].push_back(u); } scanf("%d %d", &U, &V); memset(vis, 0, sizeof(vis)); memset(sum, 0, sizeof(sum)); vis[U] = 1; cnt = 0; dfs(U, 0); if(cnt == 0) {//特判不连通的情况 printf("-1\n"); return 0; } int ans = 0; for(int i = 1; i <= n; i ++) { //cout << sum[i] << endl; if(sum[i] == cnt) {//cnt是总的路径个数,如果相等的话,说明i点在U到V的每一条路径上,即删去改点后U,V不连通 ans ++; } } printf("%d\n", ans - 2);//减2是因为起始点和结束点不应该包括在里面 return 0; }
相关文章推荐
- 图形绘制处理逻辑VC
- PAT (Basic Level) Practise:1037. 在霍格沃茨找零钱
- js-事件捕获与事件冒泡原理 IE和DOM之间存在哪些主要差别
- SVN提交代码前需要注意的事项
- 百度地图需要SHA1。
- MongoDB 聚合
- nginx配置示例
- 关于dispatch_sync死锁问题
- FindProxyForURL设置浏览器代理
- HDU2053Switch Game
- 自己写的异步下载 安卓
- 关于几篇帮助理解的帖子链接(更新中)
- Gerrit源码开发环境搭建详解
- LINUX 笔记8
- eclipse4.4反编译安装
- 杭电(hdu)2053 Switch Game 水题
- poj 3461 Oulipo (KMP入门)
- HTMLParser使用
- [leetcode][math] Missing Number
- Hadoop错误5_配置Hadoop环境变量时export‘=’not a valid identifier的一个原因