HDU 3849 By Recognizing…(求无向图的桥数目)
http://acm.hdu.edu.cn/showproblem.php?pid=3849
题意:给你一个无向图(可能不连通,但是无自环,无重边),要你输出图中的每条桥边,要求按输入边的顺序输出.
分析:
由于图可能不连通,所以我们只用tarjan(1,-1)即可.然后判断是否还有节点的pre值==0.如果存在这种点,那么该图不连通.
输出每条桥不难,直接用刘汝佳训练指南的模板即可.有点小麻烦的是题目给的边不是数字对,而是两个字符串对.且需要按输出边的顺序输出桥边.
代码中我用map来实现一个字符串到点编号的映射,那么一个输入边就是由两个字符串节点node组成的了.我们先求完所有节点的low值.然后在退出tarjan()函数后,重新扫描每一条边的两个节点u和v的low和pre值.若low[u]>pre[v]||low[v]>pre[u]
那么(u,v)边一定是桥.(仔细想想这个结论)
AC代码:
#include<cstdio>
#include<cstring>
#include<vector>
#include<map>
#include<algorithm>
using namespace std;
const int maxn=10000+10;
const int maxm=100000+10;
int n,m;
struct node
{
char s[20];
bool operator <(const node& rhs)const
{
return strcmp(s,rhs.s)<0;
}
};
map<node,int> mp;//将字符串node映射成节点编号
struct Edge
{
node u,v;
bool flag;//标记该边是不是桥
}e[maxm];
vector<int> G[maxn];
int pre[maxn],low[maxn];
int dfs_clock;
void tarjan(int u,int fa)
{
low[u]=pre[u]=++dfs_clock;
for(int i=0;i<G[u].size();i++)
{
int v=G[u][i];
if(v==fa) continue;
if(!pre[v])
{
tarjan(v,u);
low[u]=min(low[u],low[v]);
}
else low[u] = min(low[u],pre[v]);
}
}
int main()
{
int T; scanf("%d",&T);
while(T--)
{
int id=0;
scanf("%d%d",&n,&m);
mp.clear();
dfs_clock=0;
memset(pre,0,sizeof(pre));
for(int i=1;i<=n;i++) G[i].clear();
for(int i=0;i<m;i++)
{
e[i].flag=false;
scanf("%s%s",e[i].u.s,e[i].v.s);
if(mp.find(e[i].u)==mp.end()) mp[e[i].u]= ++id;
if(mp.find(e[i].v)==mp.end()) mp[e[i].v]= ++id;
int x = mp[e[i].u], y=mp[e[i].v];
G[x].push_back(y);
G[y].push_back(x);
}
tarjan(1,-1);
bool ok=true;//判断是否连通图
for(int i=1;i<=n;i++)if(!pre[i])
{
ok=false;
break;
}
if(!ok) printf("0\n");
else
{
int ans=0;//计数桥总数
for(int i=0;i<m;i++)
{
int u=mp[e[i].u], v=mp[e[i].v];
if(low[u]>pre[v]||low[v]>pre[u]) e[i].flag=true,ans++;
}
printf("%d\n",ans);
for(int i=0;i<m;i++)if(e[i].flag)
printf("%s %s\n",e[i].u.s,e[i].v.s);
}
}
return 0;
}
分享到:
相关推荐
本人准备2020年保研机试时刷的题目(虽然最后机试取消了,...来自某中流985,在HDU和vjudge平台上大概刷了400道。本文件地图(excel表格)包含了绝大部分我刷过的题目,笔记中具有思路、代码、总结和心得。 大佬勿入!
【标题】"HDU DP动态规划"涉及到的是在算法领域中的动态规划(Dynamic Programming,简称DP)技术,这是解决复杂问题的一种高效方法,尤其适用于有重叠子问题和最优子结构的问题。动态规划通常用于优化多阶段决策...
HDU的1250,主要是利用高精度加法,但是代码有点繁琐,效率不是很高
hdu1001解题报告
ACM HDU 题目分类 ACM HDU 题目分类是指对 HDU 在线判题系统中题目的分类,总结了大约十来个分类。这些分类将有助于编程选手更好地理解和解决问题。 DP 问题 DP(Dynamic Programming,动态规划)是一种非常重要...
HDU1059的代码
hdu 1574 passed sorce
本分类涵盖了图论领域的多种类型的题目,涉及到图论的基本概念、图的遍历、图的搜索、图的匹配、图的.isConnected性、图的最短路径、图的最小生成树、图的拓扑排序等多个方面。 图论是一个重要的计算机科学领域,...
hdu2101AC代码
【标题】:杭电ACMhdu1163 【描述】:这是一道源自杭州电子科技大学(Hangzhou Dianzi University,简称HDU)的ACM编程竞赛题目,编号为1163。这类问题通常需要参赛者利用计算机编程解决数学、逻辑或算法上的挑战,...
【ACM HDU】指的是在ACM(国际大学生程序设计竞赛,International Collegiate Programming Contest)中,参赛者在杭州电子科技大学(Hangzhou Dianzi University,简称HDU)的在线评测系统上完成并已解决的题目集合...
搜索 dfs 解题代码 hdu1241
【标题】"HDU题目java实现"所涉及的知识点主要集中在使用Java编程语言解决杭州电子科技大学(HDU)在线评测系统中的算法问题。HDU是一个知名的在线编程竞赛平台,它提供了大量的算法题目供参赛者练习和提交解决方案...
hdu 5007 Post Robot 字符串枚举。 暴力一下就可以了。
hdu1290 解题报告 献给杭电五十周年校庆的礼物 (切西瓜问题,即平面分割空间)
hdu 1166线段树代码
HDU最全ac代码
hdu动态规划算法集锦
hdu题目分类
HDU是杭州电子科技大学(Hangzhou Dianzi University)举办的一个在线编程竞赛平台,全称为HDU Online Judge。ACM是国际大学生程序设计竞赛(International Collegiate Programming Contest)的缩写,是一个全球性的...