【HDU 4738 Caocao's Bridges】BCC 找桥
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4738
题意:给定一个n个节点m条边的无向图(可能不连通、有重边),每条边有一个权值。判断其连通性,若双连通,输出-1;若非连通,输出0;否则,输出权值最小的桥的权值。
思路:进行双连通域分解,记下连通块的个数和所有桥的情况,对应输出结果即可。
注意对重边的处理。这里我按照上一道题学到的姿势如法炮制:先把所有边按“字典序”排序(u, v, w),这样重边聚集在一起了,然后扫描一遍,发现重边即在结构体Edge中打重边标记;由于重边一定不是桥,因此选哪个的权值实际上无所谓。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#define CLEAR(A, X) memset(A, X, sizeof(A))
#define REP(N) for(int i=0; i<(N); i++)
#define REPE(N) for(int i=1; i<=(N); i++)
#define FREAD(FN) freopen((FN), "r", stdin)
#define pb(a) push_back(a) using namespace std; const int MAX_N = ;
const int MAX_M = ;
const int INF = ;
int n, m; struct Edge
{
int v, next;
int w;
bool isBrg;
bool isDup;
}edges[MAX_M];
int numE;
int head[MAX_N];
int low[MAX_N], dfn[MAX_N], clock;
int inStack[MAX_N], S[MAX_N], topS;
int block, belong[MAX_N];
int numBrg;
int cnt;//连通块个数 void init(){
numE = ;
clock = block = topS = ;
numBrg = ;
CLEAR(low, );
CLEAR(dfn, );
CLEAR(head, -);
CLEAR(belong, );
CLEAR(inStack, );
} void addEdge(int u, int v, int w, bool isDup){
edges[numE].v = v;
edges[numE].w = w;
edges[numE].isBrg = ;
edges[numE].isDup = isDup;
edges[numE].next = head[u];
head[u] = numE++; //反向边
edges[numE].v = u;
edges[numE].w = w;
edges[numE].isBrg = ; //这里之前忘清零了,一直WA。。。
edges[numE].isDup = isDup;
edges[numE].next = head[v];
head[v] = numE++;
} void bcc(int u, int p, int isDup){
low[u] = dfn[u] = ++clock;
S[topS++] = u;
inStack[u] = ;
for(int i=head[u]; i != -; i = edges[i].next){
int v = edges[i].v;
if(v == p && (!isDup)) continue;
if(!dfn[v]){
bcc(v, u, edges[i].isDup);
low[u] = min(low[u], low[v]);
if(low[v] > dfn[u]){//bridge
numBrg++;
edges[i].isBrg = ;
edges[i^].isBrg = ;
}
}else if(inStack[v]){//backward
low[u] = min(low[u], dfn[v]);
}
}
if(low[u] == dfn[u]){//new bcc
block++;
int t;
do{
t = S[--topS];
inStack[t] = ;
belong[t] = block;
}while(t != u);
}
} struct Node
{
int u, v, w;
Node(){}
Node(int uu, int vv, int ww):u(uu), v(vv), w(ww){}
}nodes[MAX_M];
bool cmp(Node a, Node b){
if(a.u == b.u){
if(a.v == b.v) return a.w < b.w;
return a.v < b.v;
}
return a.u < b.u;
}
bool same(Node a, Node b){
return a.u == b.u && a.v == b.v;
} int main()
{
FREAD("4738.txt");
while(~scanf("%d%d", &n, &m) && !(n== && m==)){
init();
REP(m){
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
if(u > v) swap(u, v);//保持顺序
nodes[i] = Node(u, v, w);
}
sort(nodes, nodes+m, cmp);
int cur = , i = ;
int flagDup = ;
while(cur < m){
while(i < m && same(nodes[cur], nodes[i])){
flagDup = ;
i++;
}//重边一定不是桥,
if(flagDup) addEdge(nodes[cur].u, nodes[cur].v, nodes[cur].w, true);
else addEdge(nodes[cur].u, nodes[cur].v, nodes[cur].w, false);
flagDup = ;
cur = i++;
}
cnt = ;
REPE(n){
if(!dfn[i]){
bcc(i, , );
cnt++;
}
}
int ans = INF;
if(cnt > ) ans = ;//非连通
else if(cnt== && !numBrg) ans = -;//边双连通
else{//有桥
// REPE(n){
// for(int j=head[i]; j != -1; j = edges[j].next){
// int v = edges[j].v;
// if(belong[i] != belong[v])
// ans = min(ans, edges[j].w);
// }
// }
REPE(numE){
if(edges[i].isBrg)
ans = min(ans, edges[i].w);
}
if(ans == ) ans = ;//至少派一人
}
printf("%d\n", ans);
}
return ;
}
判桥用 edges[i].isBrg 或 belong[u] == belong[v]都可以,二者等价。
多组样例,我开始用第一种但忘记在addEdge中把isBrg清零了才会WA。
【HDU 4738 Caocao's Bridges】BCC 找桥的更多相关文章
- HDU 4738 Caocao's Bridges ——(找桥,求联通块)
题意:给你一个无向图,给你一个炸弹去炸掉一条边,使得整个图不再联通,你需要派人去安置炸弹,且派去的人至少要比这条边上的人多.问至少要派去多少个,如果没法完成,就输出-1. 分析:如果这个图是已经是多个 ...
- Hdu 4738 Caocao's Bridges (连通图+桥)
题目链接: Hdu 4738 Caocao's Bridges 题目描述: 有n个岛屿,m个桥,问是否可以去掉一个花费最小的桥,使得岛屿边的不连通? 解题思路: 去掉一个边使得岛屿不连通,那么去掉的这 ...
- hdu 4738 Caocao's Bridges (tarjan求桥)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4738 题目大意:给一些点,用一些边把这些点相连,每一条边上有一个权值.现在要你破坏任意一个边(要付出相 ...
- HDU 4738 Caocao's Bridges(Tarjan求桥+重边判断)
Caocao's Bridges Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- HDU 4738——Caocao's Bridges——————【求割边/桥的最小权值】
Caocao's Bridges Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u S ...
- HDU 4738 Caocao's Bridges (2013杭州网络赛1001题,连通图,求桥)
Caocao's Bridges Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- hdu 4738 Caocao's Bridges 图--桥的判断模板
Caocao's Bridges Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- HDU——4738 Caocao's Bridges
Caocao's Bridges Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- HDU 4738 Caocao's Bridges
Caocao's Bridges Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
随机推荐
- Mybatis 开发中遇见的异常及处理
1 异常信息: org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.binding.Bin ...
- c语言0 ‘0’ '\0'空格都是什么玩意儿
void main() { ; '; printf("\n%d,%c",ch,ch);//按照%d就是求编号,按照字符 printf("\n[%d],[%c]" ...
- genymotion+Oracle VM VirtualBox + eclipse + appium 脚本运行慢解决步骤
genymotion+Oracle VM VirtualBox + eclipse + appium 脚本运行慢解决步骤 1.lenove 机器启动时按F1 进入bios 设置,设置cpu virtu ...
- 在ubuntu14.04上安装maven
1.首先到Maven官网下载安装文件,目前最新版本为3.3.1,下载文件为apache-maven-3.0.3-bin.tar.gz,下载可以使用wget命令: 2.进入下载文件夹,找到下载的文件,运 ...
- WP系统推广难的原因之中的一个之我见
个人也觉得如今的Android市场几家独大,竞争太激烈.利润空间挤压太严重,有实力的厂家不如尝试剑走偏锋,在其它大佬都还没跟进的时候,把市场投向WP.先入为主,不失为良策! 话说Microsoft不开 ...
- leetcode_question_57 Insert Interval
Given a set of non-overlapping intervals, insert a new interval into the intervals (merge if necessa ...
- 【技术文档】《算法设计与分析导论》R.C.T.Lee等·第7章 动态规划
由于种种原因(看这一章间隔的时间太长,弄不清动态规划.分治.递归是什么关系),导致这章内容看了三遍才基本看懂动态规划是什么.动态规划适合解决可分阶段的组合优化问题,但它又不同于贪心算法,动态规划所解决 ...
- Android 通知栏用法例子
当程序意外退出时,可以去掉通知栏上显示的图标 1.创建TestNotificationActivity activity类, package com.notioni.test.notification ...
- 有关android 应用的plugin框架调研
1. 借助android提供的shareduserid属性使多个不同的apt共用一个userid,以扫除权限壁垒,获取插件context,继而获取view并加载插件.这种方式是建立在已经安装完成的ap ...
- 查看linux版本和内核信息
一.查看Linux内核版本命令(两种方法): 1.cat /proc/version [root@localhost ~]# cat /proc/versionLinux version 2.6.32 ...