UVa610 - Street Directions(桥的问题)

本文介绍了一种算法,用于将双向街道转换为单向街道,以减少交通事故。算法确保从每个交叉口都能到达其他所有交叉口,并提供了一个示例输入输出。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Street Directions 

According to the Automobile Collision Monitor (ACM), most fatal trafficaccidents occur ontwo-way streets. In order to reduce the number of fatalities caused bytraffic accidents, themayor wants to convert as many streets as possible into one-way streets.You have been hiredto perform this conversion, so that from each intersection, it ispossible for a motorist to driveto all the other intersections following some route.


You will be given a list of streets (all two-way) of the city.Each street connects two intersections,and does not go through an intersection. At most four streetsmeet at each intersection, andthere is at most one street connecting any pair of intersections.It is possible for an intersectionto be the end point of only one street. You may assume that itis possible for a motorist to drivefrom each destination to any other destination when every street isa two-way street.

Input 

The input consists of a number of cases. The first line of each casecontains two integers n andm. The number of intersections is n ($2 \leŸ n \leŸ 1000$), and thenumber of streets is m. Thenext m lines contain the intersections incident to each of the mstreets. The intersections arenumbered from 1 to n, and each street is listed once. If thepair $i\ j$is present, $j\ i$will not bepresent. End of input is indicated by n = m = 0.

Output 

For each case, print the case number (starting from 1) followedby a blank line. Next, printon separate lines each street as the pair $i\ j$to indicate thatthe street has been assigned thedirection going from intersection i to intersection j. For astreet that cannot be converted intoa one-way street, print both $i\ j$and $j\ i$on two different lines.The list of streets can be printedin any order. Terminate each case with a line containing asingle `#' character.


Note: There may be many possible direction assignments satisfyingthe requirements. Any such assignment is acceptable.

Sample Input 

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

Sample Output 

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
#
桥的查找问题
#include <cstdio>
#include <cstring>
#include <vector>
#include <utility>
#include <algorithm>

using namespace std;

const int N = 1010;

vector<int> g[N];
bool vis[N][N];
vector< pair<int, int> > ans;
int n, m;
int low[N], dfn[N], dfs_clock;
int t = 1;

bool input();
void solve();
void dfs(int u, int father);

int main()
{
	#ifndef ONLINE_JUDGE
		freopen("d:\\OJ\\uva_in.txt", "r", stdin);
	#endif
	
	while (input()) {
		solve();
	}
	return 0;
}

bool input()
{
	scanf("%d%d", &n, &m);
	if (n == 0 && m == 0) return false;
	
	for (int i = 0; i < N; i++) g[i].clear();
	for (int i = 0; i < m; i++) {
		int a, b;
		scanf("%d%d", &a, &b);
		g[a].push_back(b);
		g[b].push_back(a);
	}
	return true;
}

void dfs(int u, int father)
{
	dfn[u] = low[u] = ++dfs_clock;
	
	for (size_t i = 0; i < g[u].size(); i++) {
		int v = g[u][i];
		if (v == father) continue;
		if (dfn[v] == -1) {
			dfs(v, u);
			low[u] = min(low[v], low[u]);
			if (low[v] > dfn[u]) {
				ans.push_back(make_pair(u, v));
				ans.push_back(make_pair(v, u));
				vis[u][v] = vis[v][u] = true;
			} else {
				ans.push_back(make_pair(u, v));
				vis[u][v] = vis[v][u] = true;
			}
		} else {
			low[u] = min(low[u], dfn[v]);
			if (!vis[u][v]) {
				ans.push_back(make_pair(u, v));
				vis[u][v] = vis[v][u] = true;
			}
		}
	}
}

void solve()
{
	memset(dfn, -1, sizeof(dfn));
	memset(vis, false, sizeof(vis));
	dfs_clock = 0;
	ans.clear();
	
	dfs(1, 1);
	
	printf("%d\n\n", t++);
	for (size_t i = 0; i < ans.size(); i++) {
		printf("%d %d\n", ans[i].first, ans[i].second);
	}
	printf("#\n");
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kgduu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值