当前位置: 首页 > news >正文

UVa 610 Street Directions

题目描述

根据汽车碰撞监测机构(ACM\texttt{ACM}ACM)的统计,大多数致命交通事故发生在双向街道上。为了减少交通事故造成的伤亡,市长希望将尽可能多的街道改为单行街道。你需要完成这一转换,使得从每个交叉路口出发,驾驶员都能沿着某条路线到达所有其他交叉路口。

给定城市中所有街道的列表(均为双向街道)。每条街道连接两个交叉路口,且不经过其他交叉路口。每个交叉路口最多与四条街道相连,任意一对交叉路口之间最多有一条街道。可能存在只有一条街道连接的交叉路口。你可以假设当所有街道都是双向时,从任意一个目的地都能到达其他任意目的地。

输入格式

输入包含多个测试用例。每个测试用例的第一行包含两个整数nnnmmm,分别表示交叉路口的数量(2≤n≤10002 \le n \le 10002n1000)和街道的数量。接下来的mmm行每行包含两个整数,表示一条街道所连接的两个交叉路口编号(编号从111nnn)。每条街道只列出一次,如果出现i j,则不会出现j i。输入以n = m = 0结束。

输出格式

对于每个测试用例,首先输出该用例的编号(从111开始),然后输出一个空行。接下来,每行输出一个方向分配,格式为i j,表示街道方向从交叉路口iiijjj。对于无法转换为单行的街道,需要输出两行,分别为i jj i$。街道列表可以按任意顺序输出。每个测试用例的输出以单独一行#` 结束。

样例

输入

7 10 1 2 1 3 2 4 3 4 4 5 4 6 5 7 6 7 2 5 3 6 7 9 1 2 1 3 1 4 2 4 3 4 4 5 5 6 5 7 7 6 0 0

输出

1 1 2 2 4 3 1 3 6 4 3 5 2 5 4 6 4 6 7 7 5 # 2 1 2 2 4 3 1 4 1 4 3 4 5 5 4 5 6 6 7 7 5 #

题目分析

本题的核心是无向连通图的方向化问题。给定一个无向连通图,要求将尽可能多的边定向为有向边,同时保证最终的有向图仍然是强连通的(即从任意节点可以到达任意其他节点)。显然,如果一条边是桥(割边),即删除该边会导致图不连通,那么这条边必须保留双向,否则两个连通分量之间将无法相互到达。对于非桥边,由于其两端存在另一条路径,我们可以将其定向为单向,而不会破坏强连通性。因此,问题转化为:识别图中的所有桥,将非桥边定向为任意方向,桥边保留双向。

我们可以采用一种基于“尝试删除”的方法,避免显式计算桥。它遍历每条边的两个方向,尝试删除该方向(即临时从邻接表中移除该有向边),然后检查起点能否到达终点。若删除后仍然连通,说明该方向并非必须保留,可以将其删除(即只保留相反方向),从而实现单向;若删除后不连通,则必须保留该方向,最终表现为双向。这种方法在实现上较为简洁,且能直接输出满足要求的定向方案。

解题思路

  1. 存储图:使用邻接表way存储无向图,每个节点i的邻接表中包含所有与其直接相连的节点编号。由于每条边是无向的,邻接表中会同时存储i->jj->i两条有向记录。

  2. 定向过程:遍历每个节点i的邻接表,对于每条有向记录i->j(其中save = way[i][j]),检查该有向边是否已经被处理过(通过集合broken记录已处理的有向边对)。如果未处理,则尝试将其删除:

    • way[i][j]临时设为-1(表示该方向不存在)。
    • 使用深度优先搜索(DFS\texttt{DFS}DFS)检查从i出发能否到达save。若可以到达,说明删除该方向后图仍然连通,因此该方向不是必须的,可以永久删除(保持-1),并标记i->save为已处理。
    • 若不能到达,说明该方向必须保留,则恢复way[i][j] = save,并标记该方向已处理,以防止后续再次尝试删除。
  3. 输出:完成所有方向的尝试后,再次遍历邻接表,输出所有仍为正数(未被删除)的有向边。若某条无向边两个方向都被保留,则会输出两行,分别表示两个方向;若只保留一个方向,则只输出一行。

  4. 正确性保证:由于非桥边至少有一个方向可以被删除,桥边的两个方向都不能删除,最终结果满足强连通性。算法通过逐一尝试删除每个方向,保证了定向方案的有效性。

复杂度分析

  • 对于每条有向边(共2m2m2m条),尝试删除并执行一次DFS\texttt{DFS}DFS,每次DFS\texttt{DFS}DFS的时间复杂度为O(n+m)O(n + m)O(n+m)
  • 总时间复杂度为O(m⋅(n+m))O(m \cdot (n + m))O(m(n+m)),在最坏情况下m=O(n2)m = O(n^2)m=O(n2),可能较大,但由于n≤1000n \le 1000n1000且实际数据较稀疏,该算法在给定时限内可运行通过(参考代码运行时间为0.7500.7500.750秒)。
  • 空间复杂度为O(n+m)O(n + m)O(n+m)

代码实现

// Street Directions// UVa ID: 610// Verdict: Accepted// Submission Date: 2016-08-31// UVa Run Time: 0.750s//// 版权所有(C)2016,邱秋。metaphysis # yeah dot net#include<bits/stdc++.h>usingnamespacestd;vector<vector<int>>way;intvisited[1001];voiddfs(inti){for(autoe:way[i])if(e>0&&!visited[e]){visited[e]=1;dfs(e);}}boolconnected(inti,intj){memset(visited,0,sizeof(visited));dfs(i);returnvisited[j];}intmain(){cin.tie(0);cout.tie(0);ios::sync_with_stdio(false);intn,m,from,to,cases=0;while(cin>>n>>m,n){cout<<++cases<<"\n\n";way.assign(n+1,vector<int>());for(inti=1;i<=m;i++){cin>>from>>to;way[from].push_back(to);way[to].push_back(from);}set<int>broken;for(inti=1;i<=n;i++)for(intj=0;j<way[i].size();j++){intsave=way[i][j];if(broken.find(i*10000+save)==broken.end()&&broken.find(save*10000+i)==broken.end()){way[i][j]=-1;if(!connected(i,save))way[i][j]=save;elsebroken.insert(i*10000+save);}}for(inti=1;i<=n;i++)for(intj=0;j<way[i].size();j++)if(way[i][j]>0)cout<<i<<' '<<way[i][j]<<'\n';cout<<"#\n";}return0;}

总结

本题通过模拟删除有向边并检查连通性的方法,巧妙地实现了无向图的方向化,使得最终有向图保持强连通且单向边数量最大化。该方法避免了显式求桥的复杂算法,实现简单直观,适用于节点数和边数适中的场景。关键点在于理解桥与非桥边在方向化过程中的不同处理方式,以及利用DFS\texttt{DFS}DFS进行连通性检验。此解法也展示了在图上进行“试探-验证”策略的实用性。

http://www.gsyq.cn/news/1600066.html

相关文章:

  • 龙口值得长期合作防水公司
  • AIGlasses项目.env文件安全配置全解析:从密钥管理到注入防护
  • WE Learn网课助手:如何用开源工具告别熬夜刷课烦恼
  • Claude Code使用:CC配置第三方模型后,内置工具到底用的谁的?
  • 无车之境:归零后的新纪元
  • 红帆iOffice.net SQL注入漏洞深度剖析与防护实践
  • 如何快速解决微信QQ语音播放难题:silk-v3-decoder音频转换终极指南
  • 智慧职教全自动学习脚本:3分钟告别手动刷课烦恼
  • 【Agentic RL / 强化学习框架】Miles 项目技术分析---(1)--- 总体
  • API安全配置实战:从密钥管理到纵深防御体系构建
  • 终极字体资源库:15款专业字体一键获取完整指南
  • 集成学习常见概念的优缺点总结
  • Windows系统下实现多OneDrive个人账号同步的实用技巧
  • 如何快速解决Windows驱动签名问题:完整绕过指南
  • APP安全漏洞探针实战:从SAST/DAST到IAST/SCA的攻防技术解析
  • 从零到精通:yt-dlp-gui的终极视频下载指南
  • AES-CMAC算法在汽车诊断安全访问中的应用与实现
  • arXiv提交避坑指南:巧用Overleaf将PDF“伪装”为LaTeX源码
  • 【软考退税终极指南】:2024最新政策解读+实操避坑清单(附税务局内部审核逻辑)
  • 解决跨平台资源获取难题:res-downloader实战方案解析
  • 终极AMD锐龙处理器调试指南:如何深度访问SMU、PCI和MSR寄存器
  • UE4SS深度解析:如何构建专业级虚幻引擎游戏Mod开发环境
  • NVMe开发——从配置空间到BAR映射的PCIe设备初始化全解析
  • 前端转大模型:从概念到可交付结果
  • 数据科学中没有‘正确概率’:从数学本质到工程实践
  • 7-Zip终极指南:免费开源压缩工具如何帮你节省50%存储空间
  • AI专著生成全知道:从选题到完稿,AI工具助你高效完成20万字专著!
  • 3分钟上手!Android GPS位置模拟终极指南:MockGPS让你随心所欲定位
  • Python供应链安全审计:三大盲区与实战防御指南
  • Android APK逆向与安全审计:从工具链到实战漏洞挖掘