poj 2117 求割点+联通分量个数
2015-06-15 10:50
288 查看
p个点,c条边的无向图中求去掉1个点后最多形成的连通分量个数。
1、若c=0,结果即为p-1
2、否则,结果为初始连通分量个数+最大割边数
1、若c=0,结果即为p-1
2、否则,结果为初始连通分量个数+最大割边数
#include<iostream> #include<stdio.h> #include<algorithm> #include<cstring> #include<map> #include<set> #include<cmath> #include<queue> #include<vector> using namespace std; typedef unsigned __int64 uLL; typedef __int64 LL; typedef double db; struct P{ int to,next; }edge[40005]; int head[10005],cnt,dfs_clock,pre[10005],ans[10005]; void add(int u,int v) { edge[cnt].to=v; edge[cnt].next=head[u]; head[u]=cnt++; } int r; int dfs(int u,int fa) { int lowu=pre[u]=++dfs_clock,child=0; for(int i=head[u];~i;i=edge[i].next) { int v=edge[i].to; if(!pre[v]) { ++child; int lowv=dfs(v,u); lowu=min(lowu,lowv); if((u!=r&&lowv>=pre[u])||(u==r&&child>1)) ++ans[u]; } else if(pre[v]<pre[u]&&v!=fa) lowu=min(lowu,pre[v]); } //if(fa<0&&child==1) ans[u]=0; return lowu; } int main() { int i,P,C; while(~scanf("%d%d",&P,&C)&&(P+C)) { if(C==0) {printf("%d\n",P-1);continue;} cnt=dfs_clock=0; memset(pre,0,sizeof(pre)); memset(ans,0,sizeof(ans)); memset(head,-1,sizeof(head)); for(i=1;i<=C;++i) { int x,y; scanf("%d%d",&x,&y); add(x,y); add(y,x); } int s=-1,tot=0; for(i=0;i<P;++i) { if(!pre[i]) { r=i; dfs(i,-1); ++tot; } s=max(s,ans[i]); } printf("%d\n",tot+s); } return 0; }
相关文章推荐
- 正则表达
- HttpWebRequest的GetResponse或GetRequestStream偶尔超时 + 总结各种超时死掉的可能和相应的解决办法
- Linux入门篇之一:一起学习Linux吧!
- 计算出当前绘制出来的字符串宽度和高度
- Oracle EBS AutoConfig详解
- 求连续数组中唯一重复的元素
- 完全卸载Oracle11g
- jquery操作字符串常用方法总结及工作代码
- native
- [C#-3] partical修饰符
- jquery插件unobtrusive实现片段式加载
- js预加载图片方法汇总
- 大数据_数据采集分析01
- opencv2:读入摄像机视频并写入AVI视频文件
- Configure,Makefile.am, Makefile.in, Makefile文件之间关系
- 程序员如何写出一份好的文档?
- 破解静态库lib
- linux 命令——7 mv(转)
- Zend Studio 10正式版破解及汉化
- Leslie 趁还没忘掉,赶快记录下来 java.io.IOException:stream closed 异常的原因及处理 ...