poj 3177 Redundant Paths (双联通)
2016-05-07 10:44
323 查看
/******************************************************* 题目:Redundant Paths (poj 2177) 链接:http://poj.org/problem?id=3177 算法:双联通+缩点 思路:先找出所有双联通分量,把这些分量缩成一个点 再找出所有度为一的点,用这些点数加一除2就可以了 ********************************************************/ #include<cstdio> #include<cstring> #include<algorithm> #include<vector> #include<iostream> #include<stack> using namespace std; const int mx=5005; vector<int>g[mx]; stack<int>s; int dfn[mx],low[mx]; int bcc[mx],vs[mx]; int in[mx]; int dfs_cut,bcc_cut; void dfs(int u,int fa) { dfn[u]=low[u]=++dfs_cut; vs[u]=1; s.push(u); int p=1; ///去重 for (int i=0;i<g[u].size();i++) { int v=g[u][i]; if (v==fa&&p) { p=0; continue; } if (!vs[v]) { dfs(v,u); low[u]=min(low[u],low[v]); } else low[u]=min(low[u],dfn[v]); } ///缩点 if (low[u]==dfn[u]) { bcc_cut++; int x; while (1) { x=s.top(); s.pop(); bcc[x]=bcc_cut; if (x==u) break; } } } int main() { int n,m; scanf("%d%d",&n,&m); for (int i=1;i<=n;i++) g[i].clear(); bcc_cut=dfs_cut=0; while (m--) { int u,v; scanf("%d%d",&u,&v); g[u].push_back(v); g[v].push_back(u); } dfs(1,-1); for (int u=1;u<=n;u++) { for (int j=0;j<g[u].size();j++) { int v=g[u][j]; if (bcc[u]!=bcc[v]) { in[bcc[u]]++; in[bcc[v]]++; } } } int ans=0; for (int i=1;i<=bcc_cut;i++) { if (in[i]==2) ans++; } printf("%d\n",(ans+1)/2); }
相关文章推荐
- ASP.NET MVC 表单验证方式总结
- zabbix网页安装过程中mysql的sock报错
- hdu 5678 ztr loves trees (给一颗有根树,树上的每一个节点有一个权值,每次询问某个子树中所有权值的中位数)
- Android 系统移植与调试(一)Android编译环境编译服务器搭建
- HDU 4734 F(x)
- 在ASP.NET 2.0中操作数据之十九:给编辑和新增界面增加验证控件
- 获取statusbar的高度
- C++位运算
- 数据库密码过期,账号被锁解决方法
- debian下载、编译、使用Cimg的Demo
- hihoCoder 1301 筑地市场 数位dp加二分答案
- Tomcat启动分析(我们为什么要配置CATALINA_HOME环境变量)
- 飛飛(三十一)指向学生的指针
- makefile中参数定义
- 集成C#测试框架和Selenium对于Web系统实现自动化测试
- Copy List with Random Pointer
- Grunt 自动编译 Less 文件配置
- C#中treeview的问题,如何区分根节点和子节点以及根节点和根节点的兄弟节点?
- 泛型
- js实现网页图片轮换播放