poj1523 最小割+并查集
来源:互联网 发布:mac skype 下载 编辑:程序博客网 时间:2024/05/01 18:52
题目链接:http://poj.org/problem?id=1523
题意是给你一些点,每两个点连成一条边,问图中有几个割点,同时如果去除割点后,图中有多少个能够互相联通的集合,比较坑的是点不是按顺序给的,即可能不是从1开始。
求割点直接套割点模板,去除割点后,还有多少能够互相联通的点的集合,可以求出割点后,对割点dfs,凡是两个不含割点的点,并到一个集合中,最后看有多少个集合即可。
代码:
#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;const int spot=1010;const int edge=500010;struct stu{ int to,next;} a[edge];int head[spot],low[spot],num[spot],root,indexx,sizes,flag1,n,fx[spot]; //fx指祖节点bool flag[spot],flag2[spot],b[spot],have[spot];void init(){ indexx=0,sizes=0,flag1=1,n=0; memset(head,-1,sizeof(head)); memset(low,0,sizeof(low)); memset(num,0,sizeof(num)); memset(flag,0,sizeof(flag)); memset(have,0,sizeof(have));}void add_edge(int from,int to) //并查集{ a[sizes].to=to; a[sizes].next=head[from]; head[from]=sizes++; a[sizes].to=from; a[sizes].next=head[to]; head[to]=sizes++; n=max(n,from); n=max(n,to);}void dfs(int cur,int father) //求割点{ int child=0; num[cur]=++indexx; low[cur]=indexx; int k,v; for(k=head[cur]; k+1; k=a[k].next) { v=a[k].to; if(!num[v]) { child++; dfs(v,cur); low[cur]=min(low[cur],low[v]); if(cur!=root&&num[cur]<=low[cur]) flag[cur]=1; if(cur==root&&child==2) flag[cur]=1; } else if(v!=father) low[cur]=min(low[cur],num[v]); }}int finds(int x){ while(fx[x]!=x) return fx[x]=finds(fx[x]); return x;}void mix(int x,int y){ int ffx=finds(x),ffy=finds(y); if(ffx!=ffy) fx[ffx]=ffy;}void dfs_edge(int x,int j) //x下一个节点,j不能等的那个{ int v,k; for(k=head[x]; k+1; k=a[k].next) { v=a[k].to,b[x]=1; if(!b[v]) { dfs_edge(v,j); if(x!=j) mix(x,v); } }}int main(){ int x,y,i,ss=0,ans,j; while(scanf("%d",&x)&&x) { init(); scanf("%d",&y); root=x; have[x]=1; have[y]=1; add_edge(x,y); for(;;) { scanf("%d",&x); if(!x) break; scanf("%d",&y); add_edge(x,y); have[x]=1,have[y]=1; } dfs(root,root); //求割点 printf("Network #%d\n",++ss); for(i=1; i<=n; i++) { if(flag[i]) //dfs遍历边的同时,将相邻的两条点(不包含i)并到一个集,最后判断有几个集合,即去掉割点后,还剩多少个集合 { ans=0,flag1=0; for(j=1; j<=n; j++) if(have[j]) fx[j]=j; memset(b,0,sizeof(b)); memset(flag2,0,sizeof(flag2)); dfs_edge(i,i); for(j=1; j<=n; j++) flag2[finds(j)]=1; for(j=1; j<=n; j++) if(flag2[j]&&j!=i&&have[j]) ans++; printf(" SPF node %d leaves %d subnets\n",i,ans); } } if(flag1) printf(" No SPF nodes\n"); puts(""); } return 0;}
0 0
- poj1523 最小割+并查集
- poj1523(割点)
- poj1523割点&&块
- POJ1523 SPF 割点
- poj1523(割点)
- 2017百度之星资格赛 1002 度度熊的王国战略(并查集 or 无向图最小割)
- poj1523 割点+连通分量
- poj1523.SPF(割点模板)
- poj1523赤裸裸的割点
- [学习][poj1523]割点 SPF
- 【BZOJ2772】policija【BCC】【割顶】【离线】【分治】【并查集】
- 并查集与最小生成树
- 并查集模版&最小生成树
- 最小生成树kruscal+并查集
- 并查集+最小生成树_HDU_1102
- bzoj1050(最小生成树 并查集)
- 最小生成树与并查集
- 最小生成树与并查集
- 新上市Lighthouse专用芯片TS3633规格介绍
- SQL中的cast()函数详解
- Box2D 源码编译
- java基础——java.util.ConcurrentModificationException
- 好姑娘向暖而生
- poj1523 最小割+并查集
- 日常生活中有哪些十分钟就能学会并可以终生受用的技能
- AngularJS事件绑定的使用详解
- Spring Boot 实用MyBatis做数据库操作
- Longest Consecutive Sequence ---LeetCode
- hotplug_uevent机制学习笔记
- SQLServer中日期函数大全
- iOS录音错误:Deactivating an audio session that has running I/O
- mysql查询语句in和exists二者的区别和性能影响