题目链接:http://poj.org/problem?id=3352

给一个图,问加多少条边可以干掉所有的桥。

先找环,然后缩点。标记对应环的度,接着找桥。写几个例子就能知道要添加的边数是桥的个数/2取上整。

这题和3177不一样的地方在于,这个题考虑重边,而我的代码本身,饿哦考虑重边的。

考虑重边:

找出桥,然后缩点。计算缩点后度为1的连通块个数。

 /*
━━━━━┒ギリギリ♂ eye!
┓┏┓┏┓┃キリキリ♂ mind!
┛┗┛┗┛┃\○/
┓┏┓┏┓┃ /
┛┗┛┗┛┃ノ)
┓┏┓┏┓┃
┛┗┛┗┛┃
┓┏┓┏┓┃
┛┗┛┗┛┃
┓┏┓┏┓┃
┛┗┛┗┛┃
┓┏┓┏┓┃
┃┃┃┃┃┃
┻┻┻┻┻┻
*/
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <climits>
#include <complex>
#include <fstream>
#include <cassert>
#include <cstdio>
#include <bitset>
#include <vector>
#include <deque>
#include <queue>
#include <stack>
#include <ctime>
#include <set>
#include <map>
#include <cmath>
using namespace std;
#define fr first
#define sc second
#define cl clear
#define BUG puts("here!!!")
#define W(a) while(a--)
#define pb(a) push_back(a)
#define Rint(a) scanf("%d", &a)
#define Rll(a) scanf("%lld", &a)
#define Rs(a) scanf("%s", a)
#define Cin(a) cin >> a
#define FRead() freopen("in", "r", stdin)
#define FWrite() freopen("out", "w", stdout)
#define Rep(i, len) for(int i = 0; i < (len); i++)
#define For(i, a, len) for(int i = (a); i < (len); i++)
#define Cls(a) memset((a), 0, sizeof(a))
#define Clr(a, x) memset((a), (x), sizeof(a))
#define Full(a) memset((a), 0x7f7f, sizeof(a))
#define lp p << 1
#define rp p << 1 | 1
#define pi 3.14159265359
#define RT return
typedef long long LL;
typedef long double LD;
typedef unsigned long long ULL;
typedef pair<int, int> pii;
typedef pair<string, int> psi;
typedef map<string, int> msi;
typedef vector<int> vi;
typedef vector<LL> vl;
typedef vector<vl> vvl;
typedef vector<bool> vb; typedef struct Edge {
int v;
bool cut;
Edge() {}
Edge(int vv) : v(vv) { cut = ; }
}Edge; const int maxn = ;
const int maxm = ;
int n, m;
int dig[maxn];
int dfn[maxn], low[maxn], idx;
vector<Edge> G[maxn];
bool vis[maxn];
int st[maxn], top;
int belong[maxn], bcnt; void tarjan(int u, int p) {
int v;
low[u] = dfn[u] = ++idx;
vis[u] = ;
st[top++] = u;
Rep(i, G[u].size()) {
v = G[u][i].v;
if(v == p) continue;
if(!dfn[v]) {
tarjan(v, u);
low[u] = min(low[u], low[v]);
if(low[v] > dfn[u]) {
G[u][i].cut = ;
Rep(j, G[v].size()) {
if(G[v][j].v== u) {
G[v][j].cut = ;
break;
}
}
}
}
else if(vis[v]) low[u] = min(low[u], dfn[v]);
}
if(low[u] == dfn[u]) {
bcnt++;
do {
v = st[--top];
vis[v] = ;
belong[v] = bcnt;
} while(v != u);
}
} int main() {
// FRead();
int u, v;
while(~Rint(n) && ~Rint(m)) {
Rep(i, n+) G[i].cl();
Cls(vis); Cls(dig); Cls(dfn); Cls(low);
top = ; idx = ; bcnt = ;
Rep(i, m) {
Rint(u); Rint(v);
G[u].pb(Edge(v)); G[v].pb(Edge(u));
}
tarjan(, );
int ret = ;
For(u, , n+) {
Rep(i, G[u].size()) {
if(G[u][i].cut) {
dig[belong[u]]++;
}
}
}
For(i, , bcnt+) {
if(dig[i] == ) ret++;
}
printf("%d\n", (ret+)>>);
}
RT ;
}

不考虑重边:

 /*
━━━━━┒ギリギリ♂ eye!
┓┏┓┏┓┃キリキリ♂ mind!
┛┗┛┗┛┃\○/
┓┏┓┏┓┃ /
┛┗┛┗┛┃ノ)
┓┏┓┏┓┃
┛┗┛┗┛┃
┓┏┓┏┓┃
┛┗┛┗┛┃
┓┏┓┏┓┃
┛┗┛┗┛┃
┓┏┓┏┓┃
┃┃┃┃┃┃
┻┻┻┻┻┻
*/
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <climits>
#include <complex>
#include <fstream>
#include <cassert>
#include <cstdio>
#include <bitset>
#include <vector>
#include <deque>
#include <queue>
#include <stack>
#include <ctime>
#include <set>
#include <map>
#include <cmath>
using namespace std;
#define fr first
#define sc second
#define cl clear
#define BUG puts("here!!!")
#define W(a) while(a--)
#define pb(a) push_back(a)
#define Rint(a) scanf("%d", &a)
#define Rll(a) scanf("%lld", &a)
#define Rs(a) scanf("%s", a)
#define Cin(a) cin >> a
#define FRead() freopen("in", "r", stdin)
#define FWrite() freopen("out", "w", stdout)
#define Rep(i, len) for(int i = 0; i < (len); i++)
#define For(i, a, len) for(int i = (a); i < (len); i++)
#define Cls(a) memset((a), 0, sizeof(a))
#define Clr(a, x) memset((a), (x), sizeof(a))
#define Full(a) memset((a), 0x7f7f, sizeof(a))
#define lp p << 1
#define rp p << 1 | 1
#define pi 3.14159265359
#define RT return
typedef long long LL;
typedef long double LD;
typedef unsigned long long ULL;
typedef pair<int, int> pii;
typedef pair<string, int> psi;
typedef map<string, int> msi;
typedef vector<int> vi;
typedef vector<LL> vl;
typedef vector<vl> vvl;
typedef vector<bool> vb; const int maxn = ;
const int maxm = ;
int n, m;
int dig[maxn];
int pre[maxn], dfn[maxn], low[maxn];
vector<int> G[maxn];
bool vis[maxn]; void dfs(int u, int p) {
vis[u] = ;
pre[u] = p;
dfn[u] = low[u] = u;
Rep(i, G[u].size()) {
int v = G[u][i];
if(!vis[v]) dfs(v, u);
else if(v != p) low[u] = min(low[u], dfn[v]);
}
} void update(int u) {
int d = low[u];
while(u != d && u != ) {
low[u] = d;
u = pre[u];
}
} int main() {
// FRead();
int u, v;
while(~Rint(n) && ~Rint(m)) {
Rep(i, n+) G[i].cl();
Cls(vis); Cls(dig); Cls(dfn); Cls(low); Cls(pre);
Rep(i, m) {
Rint(u); Rint(v);
G[u].pb(v); G[v].pb(u);
}
For(i, , n+) if(!vis[i]) dfs(i, );
For(i, , n+) if(dfn[i] != low[i]) update(i);
For(u, , n+) {
Rep(i, G[u].size()) {
int v = G[u][i];
if(low[u] != low[v]) {
dig[low[u]]++; dig[low[v]]++;
}
}
}
int ret = ;
For(i, , n+) dig[i] /= ;
For(i, , n+) if(low[i] == i && dig[low[i]] == ) ret++;
printf("%d\n", ret % == ? ret / : ret / + );
}
RT ;
}

[POJ3352]Road Construction(缩点,割边,桥,环)的更多相关文章

  1. [POJ3352]Road Construction

    [POJ3352]Road Construction 试题描述 It's almost summer time, and that means that it's almost summer cons ...

  2. POJ3352 Road Construction 双连通分量+缩点

    Road Construction Description It's almost summer time, and that means that it's almost summer constr ...

  3. POJ-3352 Road Construction,tarjan缩点求边双连通!

    Road Construction 本来不想做这个题,下午总结的时候发现自己花了一周的时间学连通图却连什么是边双连通不清楚,于是百度了一下相关内容,原来就是一个点到另一个至少有两条不同的路. 题意:给 ...

  4. POJ3352 Road Construction (双连通分量)

    Road Construction Time Limit:2000MS    Memory Limit:65536KB    64bit IO Format:%I64d & %I64u Sub ...

  5. POJ3352 Road Construction(边双连通分量)

                                                                                                         ...

  6. POJ3352 Road Construction Tarjan+边双连通

    题目链接:http://poj.org/problem?id=3352 题目要求求出无向图中最少需要多少边能够使得该图边双连通. 在图G中,如果任意两个点之间有两条边不重复的路径,称为“边双连通”,去 ...

  7. poj3352 Road Construction & poj3177 Redundant Paths (边双连通分量)题解

    题意:有n个点,m条路,问你最少加几条边,让整个图变成边双连通分量. 思路:缩点后变成一颗树,最少加边 = (度为1的点 + 1)/ 2.3177有重边,如果出现重边,用并查集合并两个端点所在的缩点后 ...

  8. 边双联通问题求解(构造边双连通图)POJ3352(Road Construction)

    题目链接:传送门 题目大意:给你一副无向图,问至少加多少条边使图成为边双联通图 题目思路:tarjan算法加缩点,缩点后求出度数为1的叶子节点个数,需要加边数为(leaf+1)/2 #include ...

  9. poj 3352 Road Construction【边双连通求最少加多少条边使图双连通&&缩点】

    Road Construction Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 10141   Accepted: 503 ...

随机推荐

  1. 【学习总结】声明变量在@interface括号中与使用@property的区别

    方式一:直接在.h文件@interface中的大括号中声明. @interface Test : NSObject { NSString *str; // 私有变量 , 其他类无法访问,只能够该类内部 ...

  2. 在myeclipse中使用Java语言进行spark Standalone模式应用程序开发

    一.环境配置 Myeclipse中虽然已经集成了maven插件,但是由于这个插件版本较低,建立maven project会出现错误. 解决办法:自己到官网http://maven.apache.org ...

  3. Xcode8兼容iOS7手记-b

    对于Xcode8的发布,苹果也是来了个大的跳跃,默认最低支持的iOS版本为8.0,当然也并不是说8.0以下就直接放弃了,虽然表现出来的是这样,毕竟使用8.0以下系统的还是大有人在的,老项目要兼容iOS ...

  4. Careercup - Facebook面试题 - 6026101998485504

    2014-05-02 10:47 题目链接 原题: Given an unordered array of positive integers, create an algorithm that ma ...

  5. ajax正确返回数据,却进入了error分支

    .net 开发: $.ajax({ type: "POST", //post没有数据量限制 url: "ashx/PostHandle.ashx", data: ...

  6. 关于windbg的认识

    1.windbg是一个用于调试代码的工具,基础介绍:http://www.pediy.com/kssd/pediy10/94457.html 2.关于windbg和vs在代码调试方面的区别,参考:ht ...

  7. android编程常见问题-No Launcher activity found!

    新手编程常见的问题: 问题表现: console提示:No Launcher activity found! The launch will only sync the application pac ...

  8. 2186: [Sdoi2008]沙拉公主的困惑 - BZOJ

    Description 大富翁国因为通货膨胀,以及假钞泛滥,政府决定推出一项新的政策:现有钞票编号范围为1到N的阶乘,但是,政府只发行编号与M!互质的钞票.房地产第一大户沙拉公主决定预测一下大富翁国现 ...

  9. MATLAB——axis

    MATLAB——axis axis中文为“轴”之意,在matlab中用于控制坐标轴的范围和样式(颜色等). axis([XMIN XMAX YMIN YMAX]) 设置当前所绘图像的x轴和y轴的范围. ...

  10. 【Asp.net MVC ---杂七杂八】

    @RenderSection 母模板:_mainLayout.cshtml <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitio ...