uestc 方老师炸弹
2015-03-01 00:04
274 查看
转自http://www.cnblogs.com/whatbeg/p/3765625.html
Tarjan算法。
1.若u为根,且度大于1,则为割点
2.若u不为根,如果low[v]>=dfn[u],则u为割点(出现重边时可能导致等号,要判重边)
3.若low[v]>dfn[u],则边(u,v)为桥(封死在子树内),不操作。
求割点时,枚举所有与当前点u相连的点v:
1.是重边: 忽略
2.是树边: Tarjan(v),更新low[u]=min(low[u],low[v]); 子树个数cnt+1.如果low[v] >= dfn[u],说明是割点,割点数+1
3.是回边: 更新low[u] = min(low[u],dfn[v]),因为此时v是u的祖先。
关于Tarjan求割点可见:http://hi.baidu.com/lydrainbowcat/item/f8a5ac223e092b52c28d591c
代码:
Tarjan算法。
1.若u为根,且度大于1,则为割点
2.若u不为根,如果low[v]>=dfn[u],则u为割点(出现重边时可能导致等号,要判重边)
3.若low[v]>dfn[u],则边(u,v)为桥(封死在子树内),不操作。
求割点时,枚举所有与当前点u相连的点v:
1.是重边: 忽略
2.是树边: Tarjan(v),更新low[u]=min(low[u],low[v]); 子树个数cnt+1.如果low[v] >= dfn[u],说明是割点,割点数+1
3.是回边: 更新low[u] = min(low[u],dfn[v]),因为此时v是u的祖先。
关于Tarjan求割点可见:http://hi.baidu.com/lydrainbowcat/item/f8a5ac223e092b52c28d591c
代码:
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<string> #include<queue> #include<algorithm> #include<map> #include<iomanip> #include<climits> #include<string.h> #include<cmath> #include<stdlib.h> #include<vector> #include<stack> using namespace std; #define INF 1000000007 #define MAXN 40010 #define Mod 1000007 #define N 10007 #define NN 30 #define sigma_size 3 const int maxn = 6e5 + 10; using namespace std; typedef long long LL; struct CUT{ int v, num; bool operator<(const CUT a) const{ if (num == a.num) return v < a.v; return num > a.num; } }cut ; vector<int> G ; int vis , dfn , low , Time; int n, m, k; int i, j, u, v; void init() { Time = 0; for (int i = 0; i <= n; ++i) { G[i].clear(); cut[i].v = i; cut[i].num = 1; } cut[0].num = 0; memset(dfn, 0, sizeof(dfn)); memset(low, 0, sizeof(low)); memset(vis, 0, sizeof(vis)); } void Tarjan(int u, int fa) { low[u] = dfn[u] = ++Time; int cnt = 0; vis[u] = 1; int flag = 1; for (int i = 0; i<G[u].size(); i++) { int v = G[u][i]; if (v == fa && flag) //重边 { flag = 0; continue; } if (!vis[v]) //树边 { Tarjan(v, u); cnt++; low[u] = min(low[u], low[v]); if (low[v] >= dfn[u]) cut[u].num++; } else if (vis[v] == 1) //回边 low[u] = min(low[u], dfn[v]); } if (fa == -1 && cnt == 1) //为根且度数为1,不是割点 cut[u].num = 1; vis[u] = 2; return; } int main() { while (cin >> n >> m >> k) { init(); for (i = 0; i < m; ++i) { cin >> u >> v; G[u].push_back(v); G[v].push_back(u); } Tarjan(0,-1); sort(cut, cut + n); for (i = 0; i<k; i++) printf("%d %d\n", cut[i].v, cut[i].num); printf("\n"); } //system("pause"); return 0; }
相关文章推荐
- UESTC - 900 方老师炸弹 —— 割点
- UESTC 900 方老师炸弹 --Tarjan求割点及删点后连通分量数
- uestc 方老师开橙卡
- 2014 UESTC Training for Search Algorithm Problem D 方老师与素数
- UESTC 方老师与迷宫
- 2014 UESTC Training for Search Algorithm Problem F 方老师与迷宫
- uestc 方老师抢银行
- UESTC_方老师和农场 2015 UESTC Training for Graph Theory<Problem L>
- 2014 UESTC Training for Graph Theory Problem G 方老师分身 I
- uestc 方老师和缘分
- 2014 UESTC Training for Graph Theory Problem H 方老师的分身 II
- UESTC 方老师开橙卡
- uestc 方老师与迷宫(三维迷宫)
- UESTC 898 方老师和缘分 --二分图匹配+强连通分量
- uestc 851 方老师与素数
- UESTC_方老师分身 I CDOJ 914
- UESTC 899 方老师和农场 --双连通分量的构造
- 2014 UESTC Training for Graph Theory Problem I 方老师的分身 III
- uestc 方老师分身 I
- UESTC_方老师的分身 II CDOJ 915