UVA 610 - Street Directions(割边)
UVA 610 - Street Directions
题意:给定一个无向图,要求把尽可能多的边定向,使得形成一个强连通图,输出定向后的图。不能定向的边就变成两条有向边
思路:找出割边。仅仅有割边是须要定成两条的。其它的双连通分量中,边肯定都能够定向,然后在dfs不经过割边打印路径。最后在打印出割边(拆成两条)
代码:
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std; const int N = 1005; int n, m; struct Edge {
int u, v, id;
int fan;
bool iscut, used;
Edge() {}
Edge(int u, int v, int id, int fan) {
this->u = u;
this->v = v;
this->id = id;
this->fan = fan;
used = false;
iscut = false;
}
}; int pre[N], low[N], dfs_clock; vector<Edge> g[N];
vector<Edge> cut; int dfs(int u, int fa) {
int lowu = pre[u] = ++dfs_clock;
for (int i = 0; i < g[u].size(); i++) {
int v = g[u][i].v;
int id = g[u][i].id;
if (id == fa) continue;
if (!pre[v]) {
int lowv = dfs(v, id);
lowu = min(lowu, lowv);
if (lowv > pre[u]) {
cut.push_back(g[u][i]);
g[u][i].iscut = true;
g[v][g[u][i].fan].iscut = true;
}
} else lowu = min(lowu, pre[v]);
}
return low[u] = lowu;
} void find_cut(int n) {
cut.clear();
memset(pre, 0, sizeof(pre));
dfs_clock = 0;
for (int i = 0; i < n; i++) {
if (!pre[i]) {
dfs(i, 0);
}
}
} int vis[N]; void print(int u) {
vis[u] = 1;
for (int i = 0; i < g[u].size(); i++) {
if (g[u][i].iscut) continue;
if (g[u][i].used) continue;
int v = g[u][i].v;
g[u][i].used = true;
g[v][g[u][i].fan].used = true;
printf("%d %d\n", u + 1, v + 1);
if (vis[v]) continue;
print(v);
}
} int main() {
int cas = 0;
while (~scanf("%d%d", &n, &m) && n || m) {
int u, v;
for (int i = 0; i < n; i++)
g[i].clear();
for (int i = 1; i <= m; i++) {
scanf("%d%d", &u, &v);
u--; v--;
g[u].push_back(Edge(u, v, i, g[v].size()));
g[v].push_back(Edge(v, u, i, g[u].size() - 1));
}
find_cut(n);
printf("%d\n\n", ++cas);
memset(vis, 0, sizeof(vis));
for (int i = 0; i < n; i++)
if (!vis[i]) print(i);
for (int i = 0; i < cut.size(); i++) {
printf("%d %d\n", cut[i].u + 1, cut[i].v + 1);
printf("%d %d\n", cut[i].v + 1, cut[i].u + 1);
}
printf("#\n");
}
return 0;
}
UVA 610 - Street Directions(割边)的更多相关文章
- UVALive 5412 Street Directions
Street Directions Time Limit: 3000ms Memory Limit: 131072KB This problem will be judged on UVALive. ...
- POJ 1515 Street Directions (边双连通)
<题目链接> 题目大意: 有m条无向边,现在把一些边改成有向边,使得所有的点还可以互相到达.输出改变后的图的所有边(无向边当成双向的有向边输出). 解题分析: 因为修改边后,所有点仍然需要 ...
- Sabotage UVA - 10480 (输出割边)
题意:....emm...就是一个最小割最大流,.,...用dinic跑一遍.. 然后让你输出割边,就是 u为能从起点到达的点, v为不能从起点到达的点 最后在残余路径中用dfs跑一遍 能到达的路 ...
- Uva 796 Critical Links (割边+排序)
题目链接: Uva 796 Critical Links 题目描述: 题目中给出一个有可能不连通的无向图,求出这个图的桥,并且把桥按照起点升序输出(还有啊,还有啊,每个桥的起点要比终点靠前啊),这个题 ...
- POJ 1515 Street Directions --一道连通题的双连通和强连通两种解法
题意:将一个无向图中的双向边改成单向边使图强连通,问最多能改多少条边,输出改造后的图. 分析: 1.双连通做法: 双连通图转强连通图的算法:对双连通图进行dfs,在搜索的过程中就能按照搜索的方向给所有 ...
- UVA610 - Street Directions(Tarjan)
option=com_onlinejudge&Itemid=8&category=153&page=show_problem&problem=551"> ...
- POJ 1515 Street Directions
题意: 一幅无向图 将尽量多的无向边定向成有向边 使得图强连通 无向图保证是连通的且没有重边 思路: 桥必须是双向的 因此先求边双连通分量 并将桥保存在ans中 每一个双连通分量内的边一定都 ...
- uva 610(tarjan的应用)
题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=23727 思路:首先是Tarjan找桥,对于桥,只能是双向边,而对于 ...
- 【转】Tarjan&LCA题集
转自:http://blog.csdn.net/shahdza/article/details/7779356 [HDU][强连通]:1269 迷宫城堡 判断是否是一个强连通★2767Proving ...
随机推荐
- 【java基础 14】锁的粒度:ThreadLocal、volatile、Atomic和Synchronized
导读:题目中提到的几个关键字,分别是解决并发问题中,加锁所使用到的几个关键字,每个关键字代表的锁的粒度 不同,本篇博客,主要是从概念定义上,区分这几个关键字的应用场景.(PS:睡梦中,依稀记得有回面试 ...
- 设计模式(十九)观察者模式 Observer
模拟场景: 甲方提供了一个气象站的接口,气象站上面装有:温度感应装置.湿度感应装置.气压感应装置. 现在我们是乙方,需要设计一个 WeatherData 对象,从气象站获取数据,并且利用这些数据,更新 ...
- 《分布式对象存储》作者手把手教你写 GO 语言单元测试!
第一部分:如何写Go语言单元测试 Go语言内建了单元测试(Unit Test)框架.这是为了从语言层面规范写UT的方式. Go语言的命名规则会将以_test.go结尾的go文件视作单元测试代码. 当我 ...
- kb-07线段树--11--区间多重该值多种查询
/* lazy思想的运用,因为查询多种,如果全记录就太繁了,lazy就是如果该区间的每一个叶子的状态都相同就不用深入下去该值,只要暂时标记下,查询的时候也不用下去,直接计算: */ #include& ...
- JDBC链接mysql,时间时0000-00-00 00:00:00时报错
应为mysql默认最小timestamp是0001-01-01 00:00:00,所以查询出来会报错 需要加在链接的url中加入 &zeroDateTimeBehavior=convertTo ...
- c语言第二题
在我们的业务中经常会遇到很多业务,字符串会有一系列的操作,请写出以下的方法 1.写一个函数,给定char *p,char q,判断char *p中是否包含char q这个字符,包含则返回这个字符的下标 ...
- 【MFC】禁用鼠标拖拽标题栏移动窗口
解决方案:重载WM_NCLBUTTONDOWN消息 (1) .h 文件 afx_msg void OnNcLButtonDown(UINT nHitTest, CPoint point); (2) . ...
- C++的静态联编和动态联编详解
一.概述: 通常来说联编就是将模块或者函数合并在一起生成可执行代码的处理过程,同时对每个模块或者函数调用分配内存地址,并且对外部访问也分配正确的内存地址,它是计算机程序彼此关联的过程.按照联编所进行的 ...
- #define xxx do{...} while(0) 宏定义
linux内核和其他一些开源的代码中,经常会遇到这样的代码: do{ ... }while(0) 这样的代码一看就不是一个循环,do..while表面上在这里一点意义都没有,那么为什么要这么用呢? 实 ...
- C#连接OleDBConnection数据库的操作
对于不同的.net数据提供者,ADO.NET采用不同的Connection对象连接数据库.这些Connection对我们屏蔽了具体的实现细节,并提供了一种统一的实现方法. Connection类有四种 ...