poj 3352 Road Construction(边双连通分量)
来源:互联网 发布:jdbc无法连接数据库 编辑:程序博客网 时间:2024/05/22 06:29
Problem:
给一个图,问最少连多少条边可以使原图成为一个双连通分量。
Solution:
求出所有的双连通分量,缩点,看成一棵树,此时度为1的点就是叶子,而一颗度为x的树想要变成双连通图至少需要(x+1)/2条边(x/2向上取整),可以理解为一条边可以使两个点连接。
#include<cstdio>#include<iostream>#include<sstream>#include<cstdlib>#include<cmath>#include<cctype>#include<string>#include<cstring>#include<algorithm>#include<stack>#include<queue>#include<set>#include<map>#include<ctime>#include<vector>#include<fstream>#include<list>using namespace std;#define ms(s) memset(s,0,sizeof(s))typedef unsigned long long ULL;typedef long long LL;const double PI = 3.141592653589;const int INF = 0x3fffffff;const int maxn = 1005;int n, times, bcc_cnt, dfn[maxn], low[maxn], bccno[maxn];vector<int> G[maxn];bool isB[maxn][maxn];void tarjan(int u, int fa){//找到桥 dfn[u] = low[u] = ++times; for(int i = 0; i < G[u].size(); ++i){ int v = G[u][i]; if(!dfn[v]){ tarjan(v, u); low[u] = min(low[u], low[v]); if(low[v] > dfn[u]) isB[u][v] = isB[v][u] = true; } else if(fa != v) low[u] = min(low[u], dfn[v]); }}void dfs(int idx){//给边双连通分量标记 dfn[idx] = 1; bccno[idx] = bcc_cnt; for(int i = 0; i < G[idx].size(); ++i){ int v = G[idx][i]; if(isB[idx][v]) continue; if(!dfn[v]) dfs(v); }}void find_ebcc(){ bcc_cnt = times = 0; memset(dfn,0,sizeof(dfn)); memset(low,0,sizeof(low)); memset(bccno,0,sizeof(bccno)); memset(isB,0,sizeof(isB)); for(int i = 1; i <= n; ++i){//求出桥 if(!dfn[i]){ bcc_cnt++; tarjan(i, -1); } } memset(dfn,0,sizeof(dfn)); for(int i = 1; i <= n; ++i){//将点标记 if(!dfn[i]){ bcc_cnt++; dfs(i); } }}int d[maxn];int solve(){ find_ebcc(); memset(d,0,sizeof(d)); for(int i = 1; i <= n; ++i){ for(int j = 0; j < G[i].size(); ++j){ if(bccno[i] != bccno[G[i][j]]){ d[bccno[i]]++; d[bccno[G[i][j]]]++; } } } int tot = 0; for(int i = 1; i <= bcc_cnt; ++i){ if(d[i] == 2) tot++; } return (tot+1)/2;}int main(){// freopen("E:\\input.txt","r",stdin);// freopen("/home/really/Document/output","w",stdout);// ios::sync_with_stdio(false); int t, a, b; while(~scanf("%d%d", &n,&t)){ for(int i = 1; i <= n; ++i) G[i].clear(); for(int i = 0; i < t; ++i){ scanf("%d%d", &a,&b); G[a].push_back(b); G[b].push_back(a); } int ans = solve(); printf("%d\n",ans); } return 0;}
0 0
- POJ 3352 Road Construction(边双连通分量)
- POJ-3352 Road Construction (边双连通分量[Tarjan])
- poj 3352 Road Construction(边双连通分量)
- poj 3352 Road Construction(Tarjan,边双连通分量)
- [双连通分量]poj 3352 Road Construction
- poj 3352--Road Construction(双连通分量)
- POJ---3352-Road Construction(双连通分量)
- POJ 3352 Road Construction / 边双连通分量
- POJ 3352 Road Construction(边双连通分量)
- POJ 3352 Road Construction (边双连通分量)
- poj 3352 Road Construction 边双连通分量
- POJ - 3352 Road Construction(边双连通分量)
- poj 3352 Road Construction(边-双连通分量)
- POJ-3352 Road Construction(边双连通分量+缩点)
- POJ 3352 Road Construction (边双连通分量)
- POJ 3352 Road Construction(边双连通分量)
- Poj 3352 Road Construction & Poj 3177 Redundant Paths(边双连通分量+缩点)
- POJ 3352 Road Construction (边双连通分量 Tarjan缩点)
- C语言实验——数组逆序
- 轻量级orm框架-easy4net
- Java中事务的处理
- Android strings.xml中的一些小知识
- 判断出栈顺序是否合法
- poj 3352 Road Construction(边双连通分量)
- java基础知识总结
- 排序
- 杀手锏,这个调用c++代码性能更高
- 炫酷:一句代码实现标题栏、导航栏滑动隐藏。ByeBurger库的使用和实现
- Git 远程仓库
- 数列有序!
- 三层2
- apk文件结构和安装过程