hdu 4738 Caocao's Bridges 图--桥的判断模板
Caocao's Bridges
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1231 Accepted Submission(s): 478
army could easily attack Zhou Yu's troop. Caocao also built bridges connecting islands. If all islands were connected by bridges, Caocao's army could be deployed very conveniently among those islands. Zhou Yu couldn't stand with that, so he wanted to destroy
some Caocao's bridges so one or more islands would be seperated from other islands. But Zhou Yu had only one bomb which was left by Zhuge Liang, so he could only destroy one bridge. Zhou Yu must send someone carrying the bomb to destroy the bridge. There might
be guards on bridges. The soldier number of the bombing team couldn't be less than the guard number of a bridge, or the mission would fail. Please figure out as least how many soldiers Zhou Yu have to sent to complete the island seperating mission.
In each test case:
The first line contains two integers, N and M, meaning that there are N islands and M bridges. All the islands are numbered from 1 to N. ( 2 <= N <= 1000, 0 < M <= N2 )
Next M lines describes M bridges. Each line contains three integers U,V and W, meaning that there is a bridge connecting island U and island V, and there are W guards on that bridge. ( U ≠ V and 0 <= W <= 10,000 )
The input ends with N = 0 and M = 0.
3 3
1 2 7
2 3 4
3 1 4
3 2
1 2 7
2 3 4
0 0
-1
4
图的连通性问题~之求桥模板
#include "stdio.h" //本人觉得两点之间可能有多条边,这样的话,邻接矩阵就没法存了,转邻接表~
#include "string.h" #define N 1005
#define INF 0x3fffffff struct node
{
int x,y;
int weight;
int next;
}edge[4*N*N];
int idx,head[N]; int set[N]; //并查集用 int root; bool mark[N],visit[N];
int low[N],dfn[N];
int stackk[4*N*N],num; int MIN(int a,int b){ return a<b?a:b; }
void Init(){ idx=0; memset(head,-1,sizeof(head)); }
int find(int x){ return set[x]==x?set[x]:set[x]=find(set[x]); } void Add(int x,int y,int weight)
{
edge[idx].x = x;
edge[idx].y = y;
edge[idx].weight = weight;
edge[idx].next = head[x];
head[x] = idx++;
} void Union(int x,int y)
{
int fa = find(x);
int fb = find(y);
if(fa!=fb)
set[fa] = fb;
} void DFS(int x,int times,int edge_father)
{
int i,y;
int child=0;
visit[x] = true;
low[x] = dfn[x] = times;
for(i=head[x]; i!=-1; i=edge[i].next)
{
y=edge[i].y;
if(!visit[y])
{
child++;
DFS(y,times+1,i);
low[x] = MIN(low[x],low[y]);
//if(x==root && child==2) mark[root] = true; //记录顶点是否为割顶
//if(x!=root && low[y]>=dfn[x]) mark[x] = true; //记录顶点是否为割顶
if(low[y]>dfn[x]) stackk[num++] = i; //若边i为桥,存入stackk[];
}
else if(edge_father!=-1 && i!=(edge_father^1)) //若当前边不为原来他father到他的边,更新low[x];
low[x] = MIN(low[x],dfn[y]);
}
} int solve(int n)
{
int i,ans = INF;
num = 0;
memset(visit,false,sizeof(visit)); //标记点是否已访问
//memset(mark,false,sizeof(mark));
root = 1;
int times = 1;
DFS(root,times,-1);
for(i=0; i<num; ++i)
ans = MIN(ans,edge[stackk[i]].weight);
if(ans==INF) ans=-1; //不存在桥,ans=-1;
if(ans==0) ans++; //如果桥权值是零,则最少要派一人去炸桥
return ans;
} int main()
{
int i;
int n,m;
int x,y,k;
while(scanf("%d %d",&n,&m),n&&m)
{
Init();
for(i=1; i<=n; ++i) set[i] = i; //并查集用
while(m--)
{
scanf("%d %d %d",&x,&y,&k);
if(x==y) continue;
Add(x,y,k);
Add(y,x,k);
Union(x,y); //合并两点
}
bool flag = true;
for(i=1; i<=n; ++i) //有一个点不连通,则flag为false;
{
if(find(i) != find(1))
flag = false;
}
if(!flag){ printf("0\n"); continue; }
printf("%d\n",solve(n));
}
return 0;
}
//后加上的代码~~
#include "stdio.h"
#include "string.h" #define N 1010
#define INF 0x3fffffff struct node
{
int x,y;
bool visit;
int weight;
int next;
}edge[2*N*N];
int idx,head[N]; int n,m;
int time;
int low[N],dfn[N];
bool mark[N];
int st[2*N*N],num; //存割边的编号 int MIN(int x,int y){ return x<y?x:y; }
void Init(){idx=0; memset(head,-1,sizeof(head)); }
void Add(int x,int y,int k)
{
edge[idx].x = x;
edge[idx].y = y;
edge[idx].visit = false; //该条边未被访问
edge[idx].weight = k;
edge[idx].next = head[x];
head[x] = idx++;
} int set[N];
int find(int x);
void Union(int x,int y); void DFS(int x)
{
int i,y;
low[x] = dfn[x] = ++time;
for(i=head[x]; i!=-1; i=edge[i].next)
{
y = edge[i].y;
if(edge[i].visit) continue; //该边已经访问过,continue;
edge[i].visit = edge[i^1].visit = true;
if(!dfn[y])
{
DFS(y);
low[x] = MIN(low[x],low[y]);
if(low[y]>dfn[x])
st[num++] = i;
}
else
low[x] = MIN(low[x],dfn[y]);
}
} int Solve()
{
int ans = INF;
int i,j;
time = 0;
num = 0;
memset(dfn,0,sizeof(dfn));
DFS(1);
for(i=0; i<num; ++i)
{
if(ans>edge[st[i]].weight)
ans = edge[st[i]].weight;
}
if(ans==INF) ans=-1;
if(ans==0) ans=1;
return ans;
} int main()
{
bool flag;
int i,j;
int x,y,k;
while(scanf("%d %d",&n,&m),n||m)
{
Init();
for(i=1; i<=n; ++i) set[i] = i;
for(i=1; i<=m; ++i)
{
scanf("%d %d %d",&x,&y,&k);
Add(x,y,k);
Add(y,x,k);
Union(x,y);
}
flag = true;
for(i=1; i<=n; ++i)
{
if(find(i)!=find(1))
flag = false;
}
if(!flag) { printf("0\n"); continue; } //图不连通,派0个人去
printf("%d\n",Solve());
}
return 0;
} int find(int x)
{
return set[x]==x?set[x]:set[x]=find(set[x]);
}
void Union(int x,int y)
{
int fa = find(x);
int fb = find(y);
if(fa!=fb)
set[fa] = fb;
}
hdu 4738 Caocao's Bridges 图--桥的判断模板的更多相关文章
- hdu 4738 Caocao's Bridges(桥的最小权值+去重)
http://acm.hdu.edu.cn/showproblem.php?pid=4738 题目大意:曹操有一些岛屿被桥连接,每座都有士兵把守,周瑜想把这些岛屿分成两部分,但他只能炸毁一条桥,问最少 ...
- Hdu 4738 Caocao's Bridges (连通图+桥)
题目链接: Hdu 4738 Caocao's Bridges 题目描述: 有n个岛屿,m个桥,问是否可以去掉一个花费最小的桥,使得岛屿边的不连通? 解题思路: 去掉一个边使得岛屿不连通,那么去掉的这 ...
- 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 (tarjan求桥)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4738 题目大意:给一些点,用一些边把这些点相连,每一条边上有一个权值.现在要你破坏任意一个边(要付出相 ...
- 2013杭州网赛 1001 hdu 4738 Caocao's Bridges(双连通分量割边/桥)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4738 题意:有n座岛和m条桥,每条桥上有w个兵守着,现在要派不少于守桥的士兵数的人去炸桥,只能炸一条桥 ...
随机推荐
- Vector Clock/Version Clock
physical clock 机器上的物理时钟,不同的机器在同一个时间点取到的physical clock不一样,之间会存在一定的误差,NTP可以用来控制这个误差,同一个机房内的机器之间的时钟误差可以 ...
- VB 2015 的 闭包(Closure)
是的,你没看错,这篇文章讲的不是 ECMAScript . 目前 VB 14 比 C# 6 领先的功能里面,有个即将在 C# 7 实现的功能,叫做"本地方法".这个功能与" ...
- u-boot移植总结(一)start.S分析
本次移植u-boot-2010.09是基于S3C2440的FL440板子,板子自带NANDFLASH而没有NORFLASH,所以在U-BOOT启动的过程中必须实现从NANDFLASH到SDRAM的重定 ...
- Maven仓库分类
MAVEN仓库分类 Maven仓库分为:本地仓库+远程仓库两大类 远程仓库又分为:中央仓库+私服+其它公共远程仓库 1,在Maven中,任何一个依赖.插件或者项目构建的输出,都可以称之为构件 2,Ma ...
- 使用R的networkD3包画可交互的网络图
d3network包code{white-space: pre;} pre:not([class]) { background-color: white; }if (window.hljs & ...
- SQL SERVER获取数据库文件信息
MS SQL SERVER 获取当前数据库文件等信息,适用于多个版本: SELECT dbf.file_id AS FileID , dbf.name AS [FileName] , s.fi ...
- 面向企业客户的制造业CRM系统的不成熟思考
CRM就是客户关系管理(Customer Relationship Management),一直一知半解,最近有涉及这方面的需求,所以稍作研究,并思考一些相关问题. CRM是什么? CRM具体如何定义 ...
- 安装多JDK后,java编译环境和运行环境版本(JDK版本) 不一致解决:
由于之前安装过JDK1.7 ,现在一个项目是JDK1.5的,那么需要更改了环境变量了,此处不再赘述如何设置JDK 的环境变量了.然后网上找来方法: 在安装多个jdk后,出现了java -version ...
- [Xamarin.Android] 自定义控件
[Xamarin.Android] 自定义控件 前言 软件项目开发的过程中,免不了遇到一些无法使用内建控件就能满足的客户需求,例如:时速表.折线图...等等.这时开发人员可以透过自定义控件的方式,为项 ...
- play framework学习笔记之 模板引擎
模板语法 ${client.name} ${client?.name} 不能确定client是否存在的时候? #{extends /} #{doLayout /}#{get} #{set} 比如 #{ ...