求割点割边——hihoCoder 1183
来源:互联网 发布:淘宝客服中心750模板 编辑:程序博客网 时间:2024/05/20 07:58
题目链接:
https://hihocoder.com/problemset/problem/1183分析:
给出一个无向图,求出图中的所有割点和割边。题解:
从任意点开始Tarjan, 设置一个父亲数组表示当前节点的根节点,和一个标记数组表示该节点有没有被Tarjan。然后开始DFS搜索遍历。割点:
①对根节点u,若其有两棵或两棵以上的子树,则该根节点u为割点。
②对非叶子节点u(非根节点),若其中的某棵子树的节点均没有指向u的祖先节点的回边,说明删除u之后,根结点与该棵子树的节点不再连通;则节点u为割点。判断非叶子结点有没有回边:
我们用dfn[u]记录节点u在DFS过程中被遍历到的次序号,low[u]记录节点u或u的子树通过非父子边追溯到最早的祖先节点(即DFS次序号最小),那么low[u]的计算过程如下:
AC代码:
/************************************************************************* > File Name: test.cpp > Author: Akira > Mail: qaq.febr2.qaq@gmail.com ************************************************************************/#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <cstdlib>#include <algorithm>#include <queue>#include <stack>#include <map>#include <cmath>#include <vector>#include <set>#include <list>#include <ctime>typedef long long LL;typedef unsigned long long ULL;typedef long double LD;#define MST(a,b) memset(a,b,sizeof(a))#define CLR(a) MST(a,0)#define Sqr(a) ((a)*(a))using namespace std;#define MaxN 100000#define MaxM MaxN*10#define INF 0x3f3f3f3f#define bug cout<<88888888<<endl;#define MIN(x,y) (x<y?x:y)#define MAX(x,y) (x>y?x:y)int N,M;struct Edge{ int from,to,next;}edge[MaxM];int head[MaxN],cont;int vis[MaxN];int low[MaxN];int dfn[MaxN];int parent[MaxN];int Index;vector<pair<int,int> > E;int Vertex[MaxN];bool cmp(pair<int,int> a,pair<int,int> b){ if(a.first==b.first) return a.second<b.second; return a.first<b.first;}void init(){ MST(head,-1); cont=0; CLR(parent); MST(dfn,-1); CLR(vis); CLR(low); Index = 1; CLR(Vertex);}void add(int u,int v){ edge[cont].from = u; edge[cont].to=v; edge[cont].next=head[u]; head[u]=cont++;}int NIL;void Tarjan(int u) //DFS{ vis[u] = 1; low[u] = dfn[u] = Index++; // 刚搜到一个节点时low = dfn int children = 0; for(int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].to; if(!vis[v]) { children++; parent[v] = u; Tarjan(v); low[u]=MIN(low[u], low[v]); // 回溯的时候改变当前节点的low值 if(parent[u] == NIL && children > 1) { Vertex[u] = 1; } if(parent[u] != NIL && low[v] >= dfn[u]) { Vertex[u] = 1; } if( low[v] > dfn[u] ) { E.push_back(make_pair(min(u,v), max(u,v))); //cout << v << " " << u << endl; } } else if( v!=parent[u]) { low[u] = MIN(low[u], dfn[v]); } }}int main(){ while(~scanf("%d%d", &N, &M)) { init(); int u,v; while(M--) { scanf("%d%d", &u, &v); add(u, v); add(v, u); } NIL = 0; Tarjan(3); int flag=0; for(int i=1;i<=N;i++) { if(Vertex[i]) { if(flag) printf(" "); flag++; printf("%d",i); } } if(!flag) printf("Null"); printf("\n"); sort(E.begin(),E.end(),cmp); for(int i=0;i<E.size();i++) printf("%d %d\n",E[i].first, E[i].second); } system("pause");}
0 0
- 求割点割边——hihoCoder 1183
- HihoCoder ——1305
- HihoCoder——Trie树
- DP——hihoCoder 1482
- hihoCoder挑战赛B题——计数
- hihoCoder挑战赛A题——顺子
- hihoCoder(1)——hiho密码
- 最小路径覆盖——hihoCoder 118
- 状压DP——hihoCoder 1044
- 状压DP——hihoCoder 1048
- 状态压缩——hihoCoder 1087
- 搜索起步—— Rectangle Split HihoCoder
- HihoCoder第十周——已知前序中序求后序
- HihoCoder第十二周——树上DP
- hihocoder—二维字符数组匹配
- hihocoder:
- hihoCoder
- Hihocoder
- Android 源码系列之<十>从源码的角度深入理解AccessibilityService,打造自己的APP小外挂(上)
- 第七周 项目5-计数的模式匹配
- 排序算法——归并排序
- maven国内镜像 阿里云
- Chrome 启动页面被114篡改的修复
- 求割点割边——hihoCoder 1183
- 网页爬虫--scrapy入门
- oj2
- MyEclipse常用配置
- Java基础知识总结(1)
- 爬虫入门(实用向)
- 网页爬虫--scrapy进阶
- HDU:1148 Rock-Paper-Scissors Tournament
- Thread和Runnable的应用