POJ1144:Network(无向连通图求割点)
题目:http://poj.org/problem?id=1144
求割点。判断一个点是否是割点有两种判断情况:
如果u为割点,当且仅当满足下面的1条
1、如果u为树根,那么u必须有多于1棵子树
2、如果u不为树根,那么(u,v)为树枝边,当Low[v]>=DFN[u]时。
然后根据这两句来找割点就可以了。
模版题,就是题意看不懂。看了题解。这题算是废了,就当贴模版用吧。
#include <iostream> #include <stdio.h> #include <string.h> #include <algorithm> #include <stack> #define N 1010 using namespace std; struct node { int x,y,next; } eg[2*N]; int tt,head[N],dfn[N],low[N],n,m,ti; bool f[2*N]; void init() { tt=0; ti=1; memset(head,-1,sizeof(head)); memset(dfn,0,sizeof(dfn)); memset(f,false,sizeof(f)); } void add(int xx,int yy) { eg[tt].x=xx; eg[tt].y=yy; eg[tt].next=head[xx]; head[xx]=tt++; } void tarjan(int u,int fa) { dfn[u]=low[u]=ti++; int child=0; for(int i=head[u]; i!=-1; i=eg[i].next) { int v=eg[i].y; if(v==fa) continue; if(!dfn[v]) { child++; tarjan(v,u); low[u]=min(low[u],low[v]); if(low[v]>=dfn[u]) { f[u]=true; } } else //无向图没有横跨边 { low[u]=min(dfn[v],low[u]); } } if(fa<0&&child<2) f[u]=false; } int main() { int u,v; while(scanf("%d",&n)!=EOF&&n!=0) { init(); while(scanf("%d",&u)!=EOF&&u) { while(getchar()!='\n') { scanf("%d",&v); add(u,v); add(v,u); } } tarjan(1,-1); int sum=0; for(int i=1; i<=n; i++) { if(f[i]) sum++; } printf("%d\n",sum); } return 0; }
或者这么写

#include <iostream> #include <stdio.h> #include <string.h> #include <algorithm> #include <stack> #define N 1010 using namespace std; struct node { int x,y,next; } eg[2*N]; int tt,head[N],dfn[N],low[N],n,m,ti; bool f[2*N]; void init() { tt=0; ti=1; memset(head,-1,sizeof(head)); memset(dfn,0,sizeof(dfn)); memset(f,false,sizeof(f)); } void add(int xx,int yy) { eg[tt].x=xx; eg[tt].y=yy; eg[tt].next=head[xx]; head[xx]=tt++; } void tarjan(int u,int fa) { dfn[u]=low[u]=ti++; int child=0; for(int i=head[u]; i!=-1; i=eg[i].next) { int v=eg[i].y; if(v==fa) continue; if(!dfn[v]) { child++; tarjan(v,u); low[u]=min(low[u],low[v]); if(low[v]>=dfn[u]&&fa!=-1) { f[u]=true; } } else //无向图没有横跨边 { low[u]=min(dfn[v],low[u]); } } if(fa<0&&child>1) f[u]=true; } int main() { int u,v; while(scanf("%d",&n)!=EOF&&n!=0) { init(); while(scanf("%d",&u)!=EOF&&u) { while(getchar()!='\n') { scanf("%d",&v); add(u,v); add(v,u); } } tarjan(1,-1); int sum=0; for(int i=1; i<=n; i++) { if(f[i]) sum++; } printf("%d\n",sum); } return 0; }
分类:
图论
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 张高兴的大模型开发实战:(一)使用 Selenium 进行网页爬虫
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构