poj 1144 Network 联通分量
来源:互联网 发布:淘宝怎么看别人的销量 编辑:程序博客网 时间:2024/05/16 01:33
何为割点?也就是题目中的关键点。在一个无向图中,去掉一个点,这个无向图会变成多个子图,那么这个点就叫做割点
同理,割边也是如此,如果去掉一条边,能让无向图变成多个子图,那么这条边叫做割边,所谓的桥。
那么tarjan是如何求的割点的呢?
如果u为割点,当且仅当满足下面的1/2
1、如果u为树根,那么u必须有多于1棵子树
2、如果u不为树根,那么(u,v)为树枝边,当Low[v]>=DFN[u]时。
割点的求法倒是看明白了,条件1的意思是若为根,下面如果只有一颗子树,也就是整个图是强连通,那么去掉根节点,肯定不会变成多个子图,因此也不会成为割点。只有大于一颗子树,去掉根节点,才会有两个或者2个以上的子图,从而才能成为割点
条件2也比较好理解,u不为树根,那么u肯定有祖先,如果存在Low【v】>=DFN【u】时,表示u的子孙只能通过u才能访问u的祖先,这也就是说,不通过u,u的子孙无法访问u的祖先,那么如果去掉u这个节点,就会至少分为两个子图,一个是u祖先,一个是u子孙的。
#include<cstdio>#include<iostream>#include<algorithm>#include<cstring>using namespace std;struct node{ int v,next;} edge[200010];int head[20010],low[20010],dfn[20010],jilu[20010];int cnt,times,n,root;void add(int u,int v){ edge[cnt].v=v; edge[cnt].next=head[u]; head[u]=cnt++; edge[cnt].v=u; edge[cnt].next=head[v]; head[v]=cnt++;}void tarjan(int u,int fa){ int flag=0; int son=0; dfn[u]=low[u]=++times; for(int e=head[u]; e!=-1; e=edge[e].next) { int v=edge[e].v; if(v==fa&&!flag) { flag=1; continue; } if(!dfn[v]) { tarjan(v,u); son++; low[u]=min(low[u],low[v]); if((u==1&&son>1)||(u!=1&&dfn[u]<=low[v])) jilu[u]=1; } else low[u]=min(low[u],dfn[v]); }}int main(){ int ans; while(~scanf("%d",&n)&&n) { int u,v; memset(head,-1,sizeof(head)); memset(dfn,0,sizeof(dfn)); memset(jilu,0,sizeof(jilu)); times=0; cnt=0; while(~scanf("%d",&u)&&u) { while(getchar()!='\n') { scanf("%d",&v); add(u,v); } } root=0; tarjan(1,-1); ans=0; for(int i=1; i<=n; i++) { if(jilu[i]) ans++; } printf("%d\n",ans); } return 0;}下面两个我感觉差不多,但是不知道为什么是错误的,算了开学再研究吧,还是算法不熟悉
#include<cstdio>#include<iostream>#include<algorithm>#include<cstring>using namespace std;struct node{ int v,next;} edge[20010];int head[20010],low[20010],dfn[20010],jilu[20010];int cnt,times,n,root;void add(int u,int v){ edge[cnt].v=v; edge[cnt].next=head[u]; head[u]=cnt++; edge[cnt].v=u; edge[cnt].next=head[v]; head[v]=cnt++;}void tarjan(int u,int fa){ int flag=0; dfn[u]=low[u]=++times; for(int e=head[u]; e!=-1; e=edge[e].next) { int v=edge[e].v; if(v==fa&&!flag) { flag=1; continue; } if(!dfn[v]) { tarjan(v,u); low[u]=min(low[u],low[v]); if(low[v]>dfn[u]&&u!=1) jilu[u]++; else if(u==1) { root++; } } else low[u]=min(low[u],dfn[v]); }}int main(){ int ans; while(~scanf("%d",&n)&&n) { int u,v; memset(head,-1,sizeof(head)); memset(dfn,0,sizeof(dfn)); memset(jilu,0,sizeof(jilu)); times=0; cnt=0; while(~scanf("%d",&u)&&u) { while(getchar()!='\n') { scanf("%d",&v); add(u,v); } } root=0; tarjan(1,-1); ans=0; if(root>1) { ans++; } for(int i=2; i<=n; i++) { if(jilu[i]) ans++; } printf("%d\n",ans); } return 0;}
0 0
- poj 1144 Network 联通分量
- Network of Schools+强联通分量+POJ
- POJ 3694Network 双联通分量 + lca
- poj 3694Network 双联通分量+lca
- POJ 1236 Network of Schools 强联通分量 + 缩点
- poj-1236-Network of Schools-强联通分量
- poj 3694 Network(桥+边联通分量+LCA)
- poj 1236 Network of Schools (强联通分量+缩点)
- POJ 1236 Network of Schools(强联通分量)
- poj 1236 Network of Schools 强联通分量tarjan
- poj 1236 Network of Schools 强联通分量Kosaraju
- poj - 1144 - Network(连通分量)
- POJ 3177(双联通分量)
- POJ 2186 强联通分量
- POJ 1236 强联通分量
- POJ 3180 强联通分量
- POJ 1904 强联通分量
- POJ 1515 双联通分量
- Java 占用字节数
- Eclipse快捷键 整理
- 路上的CG编程
- QT5 解决汉字乱码的方法
- 比较扑克牌大小(输入总是正确)
- poj 1144 Network 联通分量
- Armadillo sparse matrix get the index of an element
- C# jmail收取邮件(带附件)
- NYOJ-整除个数(水题)
- 游戏中的常用术语
- 关注健康橱柜请选择环保陶瓷橱柜、水泥橱柜、瓷砖橱柜
- Android EditText输入字数限制总结(包括中文输入内存溢出的解决方法)
- 万物鼻祖Object和Java异常
- viewpager自动循环滑动和手动滑动(手动滑动后自动滑动延后处理)