无向连通图求割边(桥)hdu4738,hdu3849
题目链接: hdu 4738
题目大意: 曹操有N个岛,这些岛用M座桥连接起来
每座桥有士兵把守(也可能没有)
周瑜想让这N个岛不连通,但只能炸掉一座桥
并且炸掉一座桥需要派出不小于守桥士兵数的人去
解题思路: 首先判断图是否连通,不连通则不需要去炸桥,输出0
图连通,则可以用Tarjan找割边
割边不存在输出-1表示不能达到目的
找到所有的割边,只需要炸掉其中守兵数最少的桥即可
PS: 桥的守兵数为0时,也需要派出一个人去炸桥!
求桥的第一种写法:
#include"string.h"
#include"stdio.h"
#include"algorithm"
#include"iostream"
#include"stack"
#define M 1111
#define inf 999999999
using namespace std;
struct st
{
int u,v,w,next;
}edge[M*M*];
int head[M],dfn[M],low[M],n,t,index,num;
int use[M],belong[M];
void init()
{
t=;
memset(head,-,sizeof(head));
}
void add(int u,int v,int w)
{
edge[t].u=u;
edge[t].v=v;
edge[t].w=w;
edge[t].next=head[u];
head[u]=t++;
}
stack<int>q;
void tarjan(int u,int id)
{
dfn[u]=low[u]=++index;
q.push(u);
use[u]=;
for(int i=head[u];i!=-;i=edge[i].next)
{
if(i==(^id))continue;
int v=edge[i].v;
if(!dfn[v])
{
tarjan(v,i);
low[u]=min(low[u],low[v]);
}
else if(use[v])
low[u]=min(low[u],dfn[v]);
}
if(low[u]==dfn[u])
{
num++;
int v;
do
{
v=q.top();
q.pop();
use[v]=;
belong[v]=num;
}while(u!=v);
}
}
int solve()
{
index=num=;
int ans=;
memset(dfn,,sizeof(dfn));
memset(low,,sizeof(low));
for(int i=;i<=n;i++)
{
if(!dfn[i])
{
ans++;
tarjan(i,-);
}
}
return ans;
}
int main()
{
int m;
while(scanf("%d%d",&n,&m),m||n)
{
init();
while(m--)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
add(a,b,c);
add(b,a,c);
}
int msg=solve();
int mini=inf;
for(int i=;i<t;i+=)
{
int u=edge[i].u;
int v=edge[i].v;
if(belong[u]!=belong[v])
mini=min(mini,edge[i].w);
}
if(msg>)
printf("0\n");
else if(mini>=inf)
printf("-1\n");
else
{ if(mini==)
printf("1\n");
else
printf("%d\n",mini);
}
}
}
求桥的第二种写法:
#include"string.h"
#include"stdio.h"
#include"iostream"
#define M 1111
#define inf 999999999
using namespace std;
struct st
{
int u,v,w,next;
}edge[M*M*];
int head[M],dfn[M],low[M],bridge[M],n,t,index,num,mini,flag;
void init()
{
t=;
memset(head,-,sizeof(head));
}
void add(int u,int v,int w)
{
edge[t].u=u;
edge[t].v=v;
edge[t].w=w;
edge[t].next=head[u];
head[u]=t++;
}
void tarjan(int u,int id)
{
dfn[u]=low[u]=++index;
int i;
for(i=head[u];i!=-;i=edge[i].next)
{
if(i==(^id))continue;
int v=edge[i].v;
if(!dfn[v])
{
tarjan(v,i);
low[u]=min(low[u],low[v]);
if(low[v]>dfn[u])
{
bridge[num++]=i;
if(mini>edge[i].w)
mini=edge[i].w;
} }
low[u]=min(low[u],dfn[v]);
}
}
void solve()
{
index=num=flag=;
memset(dfn,,sizeof(dfn));
memset(low,,sizeof(low));
for(int i=;i<=n;i++)
{
if(!dfn[i])
{
flag++;
tarjan(i,-);
} }
}
int main()
{
int m;
while(scanf("%d%d",&n,&m),m||n)
{
init();
while(m--)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
add(a,b,c);
add(b,a,c);
}
mini=inf;
solve();
if(flag>)
printf("0\n");
else if(num==)
printf("-1\n");
else
{
if(mini==)
printf("1\n");
else
printf("%d\n",mini);
}
}
}
题目链接:hdu3849
题目大意:给出一些字符串网络联通图,问有多少个关键路径破坏后使图不连通,若图本身不连通的时候就直接输出0
程序:
#include"string.h"
#include"stdio.h"
#include"iostream"
#include"stdlib.h"
#define M 10009
#define inf 999999999
#include"map"
#include"string"
using namespace std;
int cmp(const void *a,const void *b)
{
return *(int*)a-*(int*)b;
}
struct st
{
int u,v,next;
}edge[M*];
int head[M],dfn[M],low[M],bridge[M],n,t,index,num,flag;
char mp1[M][];
void init()
{
t=;
memset(head,-,sizeof(head));
}
void add(int u,int v)
{
edge[t].u=u;
edge[t].v=v;
edge[t].next=head[u];
head[u]=t++;
}
void tarjan(int u,int id)
{
dfn[u]=low[u]=++index;
int i;
for(i=head[u];i!=-;i=edge[i].next)
{
if(i==(^id))continue;
int v=edge[i].v;
if(!dfn[v])
{
tarjan(v,i);
low[u]=min(low[u],low[v]);
if(low[v]>dfn[u])
bridge[num++]=i;
}
low[u]=min(low[u],dfn[v]);
}
}
void solve()
{
index=num=flag=;
memset(dfn,,sizeof(dfn));
memset(low,,sizeof(low));
for(int i=;i<=n;i++)
{
if(!dfn[i])
{
flag++;
tarjan(i,-);
} }
}
int main()
{
int T,m,i;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
int k=;
init();
map<string,int>mp;
while(m--)
{
char ch1[],ch2[];
scanf("%s%s",ch1,ch2);
if(mp[ch1]==)
mp[ch1]=k++;
if(mp[ch2]==)
mp[ch2]=k++;
int x=mp[ch1];
int y=mp[ch2];
add(x,y);
add(y,x);
strcpy(mp1[x],ch1);
strcpy(mp1[y],ch2);
}
solve();
if(flag>)
{
printf("0\n");
continue;
}
qsort(bridge,num,sizeof(bridge[]),cmp);
printf("%d\n",num);
for(i=;i<num;i++)
{
int j=bridge[i];
j=j/*;
int u=edge[j].u;
int v=edge[j].v;
printf("%s %s\n",mp1[u],mp1[v]);
}
}
}
无向连通图求割边(桥)hdu4738,hdu3849的更多相关文章
- ZOJ 2588 Burning Bridges(无向连通图求割边)
题目地址:ZOJ 2588 由于数组开小了而TLE了..这题就是一个求无向连通图最小割边.仅仅要推断dfn[u]是否<low[v],由于low指的当前所能回到的祖先的最小标号,增加low[v]大 ...
- 无向连通图求割边+缩点+LCA
Network Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 7082 Accepted: 2555 Descripti ...
- ZOJ2588:Burning Bridges(无向连通图求割边)
题目:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1588 吐下槽,不得不说ZOJ好坑,模版题做了一个多小时. 题意:* ...
- HDU 4738——Caocao's Bridges——————【求割边/桥的最小权值】
Caocao's Bridges Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u S ...
- ZOJ 2588 Burning Bridges(求含重边的无向连通图的割边) - from lanshui_Yang
Burning Bridges Time Limit: 5 Seconds Memory Limit: 32768 KB Ferry Kingdom is a nice little country ...
- 无向连通图求割点(tarjan算法去掉改割点剩下的联通分量数目)
poj2117 Electricity Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 3603 Accepted: 12 ...
- POJ1523:SPF(无向连通图求割点)
题目:http://poj.org/problem?id=1523 题目解析: 注意题目输入输入,防止PE,题目就是求割点,并问割点将这个连通图分成了几个子图,算是模版题吧. #include < ...
- Light OJ 1026 - Critical Links (图论-双向图tarjan求割边,桥)
题目大意:双向联通图, 现在求减少任意一边使图的联通性改变,按照起点从小到大列出所有这样的边 解题思路:双向边模版题 tarjan算法 代码如下: #include<bits/stdc++.h& ...
- POJ1144:Network(无向连通图求割点)
题目:http://poj.org/problem?id=1144 求割点.判断一个点是否是割点有两种判断情况: 如果u为割点,当且仅当满足下面的1条 1.如果u为树根,那么u必须有多于1棵子树 2. ...
随机推荐
- hive 表优化
一.外部表和内部表的区别 (1)创建表时指定external关键字,就是外部表,不指定external就是内部表 (2)内部表删除后把元数据和数据都删除了,外部表删除后只是删除了元数据,不会删除hdf ...
- Sublime的Package Control安装方法
Package Control插件本身是一个为了方便管理插件的插件 最简单的方式是通过Sublime Text 3的console命令界面进行安装 Sublime text3 import urlli ...
- Python easyGUI 登录框 非空验证
import easygui as g msg='欢迎注册' title='注册' fieldNames=['*用户名','*密码','*重复密码','真实姓名','手机号','QQ','e-mail ...
- Mysql主从热备
mysql主从配置比较不错的文章,大家可以参考下~ https://www.cnblogs.com/kissdodog/p/5422195.html
- Selenium 基本用法
如下,使用 Selenium 打开淘宝首页并获取页面源代码: from selenium import webdriver browser = webdriver.Chrome() # 声明一个浏览器 ...
- Senium 简介
有时候我们在用 requests 抓取页面的时候,得到的结果可能和在浏览器中看到的不一样,在浏览器中可以看到正常显示的页面数据,但是使用 requests 得到的结果并没有.这是因为 requests ...
- [Linux] 特殊文件 /dev/zero
/dev/zero 是类 Unix 系统中一个特殊的文件,当读取该文件时,它会提供无限的空字符 null.它的一个主要用途是提供字符流来初始化数据存储,也就是使用空字符覆盖目标数据.另一个常见的用法是 ...
- (转载)Recyclerview | Intent与Bundle在传值上的区别 | 设置布局背景为白色的三种方法
用Recyclerview实现列表分组.下拉刷新以及上拉加载更多 http://www.jianshu.com/p/be62ce21ea57 Intent与Bundle在传值上的区别http://b ...
- PHP 图片 平均分割
$filename = 'D://WWW/1.jpg'; $p = 5; // Get new sizes list($width, $height) = getimagesize($filename ...
- Material Design系列第三篇——Using the Material Theme
Using the Material Theme This lesson teaches you to Customize the Color Palette Customize the Status ...