无向图求割顶双连通分量

poj1144:

模板题,不过输入的方式真的真的是非常非常蛋疼。。。记住了。。。

 1 #include<cstdio>
 2 #include<vector>
 3 #include<cstring>
 4 #include<iostream>
 5 #include<algorithm>
 6 using namespace std;
 7 #define rep(i,n) for(int i=1;i<=n;i++)
 8 #define clr(x,c) memset(x,c,sizeof(x))
 9 const int nmax=105;
10 int dfn[nmax],low[nmax],iscut[nmax],n,dfn_clock;
11 vector<int>f[nmax];
12 int get(char *ch){
13     int x=0;
14     for(int i=0;ch[i];i++)
15       x=x*10+ch[i]-‘0‘;
16     return x;
17 }
18 int dfs(int u,int fa){
19     low[u]=dfn[u]=++dfn_clock;
20     int child=0;
21     for(int i=0;i<f[u].size();i++){
22         int v=f[u][i];
23         if(!dfn[v]){
24             child++;
25             dfs(v,u);
26             low[u]=min(low[u],low[v]);
27             if(low[v]>=dfn[u])
28               iscut[u]=1;
29         }
30         else if(dfn[v]<dfn[u]&&v!=fa)
31           low[u]=min(low[u],dfn[v]);
32     }
33     if(fa<0&&child==1) iscut[u]=0;
34     return low[u];
35
36 }
37 int main(){
38     while(scanf("%d",&n)&&n){
39         dfn_clock=0;
40         clr(dfn,0);clr(iscut,0);
41         rep(i,n) f[i].clear();
42         char ch[10];
43         while(scanf("%s",ch)==1){
44             if(ch[0]==‘0‘) break;
45             int u=get(ch);
46             while(scanf("%s",ch)==1){
47                 int v=get(ch);
48                 f[u].push_back(v);
49                 f[v].push_back(u);
50                 char t=getchar();
51                 if(t==‘\n‘) break;
52             }
53         }
54         dfs(1,-1);
55         int ans=0;
56         rep(i,n)
57           if(iscut[i])
58             ans++;
59         printf("%d\n",ans);
60     }
61     return 0;
62 }
时间: 2025-01-13 07:23:04

无向图求割顶双连通分量的相关文章

无向图求割顶与桥

无向图求割顶与桥 对于无向图G,如果删除某个点u后,连通分量数目增加,称u为图的关节点或割顶.对于连通图,割顶就是删除之后使图不再连通的点.如果删除边(u,v)一条边,就可以让连通图变成不连通的,那么边(u,v)是桥. 具体的概念和定义比较多,在刘汝佳<<训练指南>>P312-314页都有详细的介绍. 下面来写求无向图割顶和桥的DFS函数.我们令pre[i]表示第一次访问i点的时间戳,令low[i]表示i节点及其后代所能连回(通过反向边)的最早祖先的pre值. 下面的dfs函数返回

UVA 315 :Network (无向图求割顶)

题目链接 题意:求所给无向图中一共有多少个割顶 用的lrj训练指南P314的模板 #include<bits/stdc++.h> using namespace std; typedef long long LL; const int N=109; struct Edge { int to,next; Edge(){} Edge(int _to,int _next) { to=_to; next=_next; } }edge[N*N*2]; int head[N]; int dfn[N],lo

无向图求割顶和桥总结

1.求能够分成几个联通分量什么的一般都在dfs中间那里if(...>...) cnt[i],iscut[i]维护一下就OK了. 2.根结点特别需要注意. 好像就没了→_→

poj 1144 Network【无向图求割顶模板题】

Description A Telephone Line Company (TLC) is establishing a new telephone cable network. They are connecting several places numbered by integers from 1 to N. No two places have the same number. The lines are bidirectional and always connect together

连通分量 无向图的割顶和桥 无向图的双连通分量 有向图的强连通分量

时间戳 dfs_clock :说白了就是记录下访问每个结点的次序.假设我们用 pre 保存,那么如果 pre[u] > pre[v], 那么就可以知道先访问的 v ,后访问的 u . 现在给定一条边, (u, v), 且 u 的祖先为 fa, 如果有 pre[v] < pre[u] && v != fa, 那么 (u, v) 为一条反向边. 1 求连通分量: 相互可达的节点称为一个连通分量: #include <iostream> #include <cstd

无向图的割顶和桥

割顶: 关键点,删掉这个点后,图的连通分量 + 1: 桥: 在割顶的基础上,发现删除 (u,v) 这条边,图就变成非连通的了. 如何找出所有割顶和桥: 时间戳: 在无向图的基础上,DFS建树的过程中,各点进栈和出栈的时间 dfs_clock,进栈的时间 pre[],出栈的时间 post[] 在DFS程序中的体现就是: void previst(int u) { pre[u]= ++dfs_clock; } void postvist(int u) { post[u] = ++dfs_clock;

图论(无向图的割顶):POJ 1144 Network

Network Description A Telephone Line Company (TLC) is establishing a new telephone cable network. They are connecting several places numbered by integers from 1 to N . No two places have the same number. The lines are bidirectional and always connect

【模板】无向图的割顶

无向图的割顶: Vector <int> G[] :邻接表存图 Int pre[] :存储时间戳 Int low[] : u及其后代所能连回的最早的祖先的pre值 Int iscut[] : =true表示是割顶,=false不是割顶 Dfs函数在主函数调用时,fa预设为-1. vector <int> G[MAXN]; int pre[MAXN],iscut[MAXN],low[MAXN],dfs_clock; int dfs(int u,int fa) { int lowu=p

无向图的割顶(poj1523,1144)

割顶:表示无向图中的点,这个点删除之后,原图不在联通,这样的点就是割顶. 怎么求一个图中的割顶呢? 把无向图变成一颗树,dfs时候搜索到在dfs树上的称为树边,搜索是出现后代指向祖先的边称为反向边. 对于根节点,当他存在两个或两个以上的子节点时,那么他就是割顶. 而对于其他节点u,当且仅当u存在一个子节点v,使得v及其所有的后代都没有反向边连回u的祖先时,u是一个割顶. 那么判断就很简单,这里给出两个模板: 题目:poj1523 和 1144都是裸的求割顶的题目 通用模板: #include <