UVA610 Street Directions Solution

topic analysis

A bridge problem ( a little harder than a template ).

We want to choose some edges in an undirected graph so that when they become directed edges, the graph is still connected.

Rather than thinking about which edges to choose to change, consider which edges cannot be changed .

Obviously, in a directed graph, if the bridge becomes a one-way edge, the graph must not be connected (it can be understood in conjunction with the definition of bridge).

Then we only need to find the bridges, that is, the edges that cannot be changed, and output them twice (as required by the title), then the remaining edges can be changed, just output them once.

Code

We write this question based on Tarjan's template code for finding bridges. (Why do you use Tarjan to find bridges, needless to say.)

  • Overview: It is very simple, it cannot be changed if it is a bridge, and it cannot be changed if it is not a bridge.
  • Details: Remember to judge the heavy edge. If it is a heavy edge, directly process the next node. If it is not a heavy edge and is not a bridge, just output it directly.

AC code

#include<bits/stdc++.h>
using namespace std;

const int maxn = 4005;
int T;
int n, m;
int cnt, hd[maxn];
struct node{
    
    
	int to, nxt;
}e[maxn * 2];
int dfn[maxn], low[maxn];
int tmp;

void init ()
{
    
    
	cnt = tmp = 0;
	memset (dfn, 0, sizeof dfn);
	memset (low, 0, sizeof low);
	memset (e, 0, sizeof e);
	memset (hd, 0, sizeof hd);
}

void add (int u, int v)
{
    
    
	e[++cnt].to = v;
	e[cnt].nxt = hd[u];
	hd[u] = cnt;
}

void tarjan (int u, int fa)
{
    
    
	int jdg = 0;
	dfn[u] = low[u] = ++tmp;
	for (int i = hd[u]; i; i = e[i].nxt)
	{
    
    
		int v = e[i].to;
		jdg = 0;
		if (!dfn[v])
		{
    
    
			tarjan (v, u);
			low[u] = min (low[u], low[v]);
			if (low[v] > dfn[u])
			{
    
    
				printf ("%d %d\n%d %d\n", u, v, v, u);
				jdg = 1;
			}
		}
		else if (dfn[v] < dfn[u] and v != fa) low[u] = min (low[u], dfn[v]);
		else continue;
		if (jdg == 0) printf ("%d %d\n", u, v);
	}
}

int main ()
{
    
    
	int T = 0;
	while (1)
	{
    
    
		scanf ("%d %d", &n, &m);
		if(!n and !m) break;
		init ();
		for (int i = m; i > 0; i--)
		{
    
    
			int u, v;
			scanf ("%d %d", &u, &v);
			add (u, v), add (v, u);
		}
		cout << ++T << endl << endl;
		for (int i = 1; i <= n; i++)
		{
    
    
			if (!dfn[i]) tarjan (i, -1);
		}
		cout << "#" << endl;
	}
	return 0;
}

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=324098413&siteId=291194637