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个兵守着,现在要派不少于守桥的士兵数的人去炸桥,只能炸一条桥 ...
随机推荐
- JavaScript一些函数
1.prompt()函数:有两个参数,一个是显示用户输入框上面的标签,另一个是输入框的初始值.用来接收用户输入的值,然后把它返回到代码中: 例如: <doctype html> <h ...
- 与众不同 windows phone (41) - 8.0 相机和照片: 通过 AudioVideoCaptureDevice 捕获视频和音频
[源码下载] 与众不同 windows phone (41) - 8.0 相机和照片: 通过 AudioVideoCaptureDevice 捕获视频和音频 作者:webabcd 介绍与众不同 win ...
- css中inline、block、inline-block的区别
http://www.cnblogs.com/fxair/archive/2012/07/05/2577280.html display:inline就是将元素显示为块级元素. block元素的特点是 ...
- mybatis mapper association collection
1.Question Description: sometimes, POJO bean contains another bean or collection as property, it's s ...
- windows下使用makecert命令生成自签名证书
1.makecert命令路径 C:\Program Files (x86)\Windows Kits\8.1\bin\x64 2.生成一个自签名证书 makecert -r -pe -n " ...
- android studio :com.android.support:appcompat-v7:21.+ 报错
android studio :com.android.support:appcompat-v7:21.+ 报错: 在project——>app——>build.gradle修改: app ...
- 关于一个js连续赋值问题之我见(词略穷,见谅)
前几天在搜索面试题时发现了这么一段代码,执行完后感觉完全不与所想的一样 var a = { n : 1 }; var b = a; a.x = a = {n : 2}; console.log(a.x ...
- Atitit.HTTP 代理原理及实现 正向代理与反向代理attilax总结
Atitit.HTTP 代理原理及实现 正向代理与反向代理attilax总结 1. 普通代理1 1.1.1. 普通代理2 2. 隧道代理3 3. 反向代理 4 4. 正向代理也可以使用apache实现 ...
- iOS 新窗口在最上层
有的时候需要弹出一个UIView 在整个视图的最上方,使用 [self.view addsubview : view] 一般就可以了,但是这样不严谨,因为这是一个tableview,那么这个view ...
- 无需cygwin,使用NDK进行开发
NDK从7开始自带编译器,在windows上无需配置cygwin的环境. 在eclips中配置NDK路径 在eclipse中点击菜单栏window-Perferences,配置NDK的路径. 在工程中 ...