Street Directions
Street Directions |
According to the Automobile Collision Monitor (ACM), most fatal traffic accidents occur on two-way streets. In order to reduce the number of fatalities caused by traffic accidents, the mayor wants to convert as many streets as possible into one-way streets. You have been hired to perform this conversion, so that from each intersection, it is possible for a motorist to drive to 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 streets meet at each intersection, and there is at most one street connecting any pair of intersections. It is possible for an intersection to be the end point of only one street. You may assume that it is possible for a motorist to drive from each destination to any other destination when every street is a two-way street.
Input
The input consists of a number of cases. The first line of each case contains two integers n and m. The number of intersections is n (![$2 \le? n \le? 1000$](http://uva.onlinejudge.org/external/6/610img1.gif)
![$i\ j$](http://uva.onlinejudge.org/external/6/610img2.gif)
![$j\ i$](http://uva.onlinejudge.org/external/6/610img3.gif)
Output
For each case, print the case number (starting from 1) followed by a blank line. Next, print on separate lines each street as the pair![$i\ j$](http://uva.onlinejudge.org/external/6/610img2.gif)
![$i\ j$](http://uva.onlinejudge.org/external/6/610img2.gif)
![$j\ i$](http://uva.onlinejudge.org/external/6/610img3.gif)
Note: There may be many possible direction assignments satisfying the 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<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<vector>
#include<stack>
#include<string.h>
using namespace std;
const int maxn = 1000+10;
struct Edge
{
Edge(int uu,int vv) : u(uu) , v(vv) { }
int u;
int v;
};
bool cmp(const Edge & e1 , const Edge & e2)
{
if (e1.u==e2.u) return e1.v < e2.v;
return e1.u < e2.u;
}
vector<int> G[maxn];
vector<Edge> ans;
int dfs_clock , n , m , pre[maxn];
bool vis[maxn][maxn];
bool is_bridge[maxn][maxn];
void init()
{
ans.clear();
memset(pre,0,sizeof(pre));
dfs_clock = 0;
for (int i = 1 ; i <= n ; ++i) G[i].clear();
}
void input()
{
int u , v;
while (m--)
{
scanf("%d%d",&u,&v);
is_bridge[u][v] = is_bridge[v][u] =
vis[u][v] = vis[v][u] = false;
G[u].push_back(v);
G[v].push_back(u);
}
}
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];
if (v==fa) continue;
if (!pre[v])
{
int lowv = dfs(v,u);
lowu = min(lowu,lowv);
if (lowv > pre[u])
{
is_bridge[u][v] = is_bridge[v][u] = true;
ans.push_back(Edge(u,v));
ans.push_back(Edge(v,u));
}
} else if (lowu > pre[v]) lowu = pre[v];
}
return lowu;
}
void dfs1(int u,int fa)
{
for (int i = 0 ; i < G[u].size() ; ++i)
{
int v = G[u][i];
if (is_bridge[u][v] || vis[u][v] || v==fa) continue;
vis[u][v] = vis[v][u] = true;
ans.push_back(Edge(u,v));
dfs1(v,u);
}
}
void solve()
{
dfs(1,-1);
for (int i = 1 ; i <= n ; ++i) dfs1(i,-1);
sort(ans.begin(),ans.end(),cmp);
for (int i = 0 ; i < ans.size() ; ++i) printf("%d %d\n",ans[i].u,ans[i].v);
}
int main()
{
int k = 0;
while (scanf("%d%d",&n,&m),n+m)
{
++k;
init();
input();
printf("%d\n\n",k);
solve();
printf("#\n");
}
}