POJ1515

来源:互联网 发布:洛氏结构源码 编辑:程序博客网 时间:2024/06/05 05:57
Street Directions
Time Limit: 1000MS Memory Limit: 10000KTotal Submissions: 922 Accepted: 487 Special Judge

Description

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 <= n <= 1000), and the number of streets is m. The next m lines contain the intersections incident to each of the m streets. The intersections are numbered from 1 to n, and each street is listed once. If the pair i j is present, j i will not be present. End of input is indicated by n = m = 0. 

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 to indicate that the street has been assigned the direction going from intersection i to intersection j. For a street that cannot be converted into a one-way street, print both i j and j i on two different lines. The list of streets can be printed in any order. Terminate each case with a line containing a single `#' character. 

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

Sample Input

7 101 21 32 43 44 54 65 76 72 53 67 91 21 31 42 43 44 55 65 77 60 0

Sample Output

11 22 43 13 64 35 25 46 46 77 5#21 22 43 14 14 34 55 45 66 77 5

#

题目大意:有m条无向边,现在把一些边改成有向边,使得所有的点还可以互相到达。输出改变后的图的所有边(无向边输出两次,有向边输出一次)。

题解:

考虑双联通分量的定义:在一个无向子图中,每两点u,v之间存在两条或以上的道路,则这个子图是双连通子图。而双联通分量就是一个个极大双连通子图。

那么,在一个双连通分量里,所有的边都可以是有向边。也就是,如果保证所有的割边是双向的,那么就符合题目条件了。

#include <cstdio>#include <iostream>#include <cstring>#include <algorithm>#include <string>#include <cstdlib>#include <bitset>#include <fstream>#include <queue>#include <stack>#include <map>#include <set>#include <ctime>#include <deque>#include <vector>#include <complex>#include <utility>using namespace std;typedef long long LL;#define INF 0x3fffffff#define Maxn 100010int dfn[Maxn],low[Maxn];int tim;struct Edge{int from,to,nocut;};vector<Edge> edges;vector<int> adj[Maxn];int n,m;void AddEdge(int x,int y){edges.push_back((Edge){x,y,-1});edges.push_back((Edge){y,x,-1});int len = edges.size();adj[x].push_back(len-2);adj[y].push_back(len-1);} void dfs(int u,int pre){int len = adj[u].size();dfn[u] = low[u] = ++tim;for(int i=0;i<len;i++){Edge &v = edges[adj[u][i]];Edge &_v = edges[adj[u][i] ^ 1];if(v.to == pre) continue;if(v.nocut != -1) continue;v.nocut = 1;_v.nocut = 0; if(dfn[v.to]==0){dfs(v.to,u);low[u] = min(low[u],low[v.to]);if(dfn[u]<low[v.to])//割边 {v.nocut = 1;_v.nocut = 1;}}else low[u] = min(low[u],dfn[v.to]);}}void init(){tim = 0;edges.clear();for(int i=0;i<Maxn;i++)adj[i].clear(),dfn[i] = low[i] = 0;}int main(){int T = 0;while( ( ~scanf("%d%d",&n,&m) ) && n && m){printf("%d\n\n",++T);init();int x,y;while(m--){scanf("%d%d",&x,&y);AddEdge(x,y);}dfs(1,1);for(int i=0;i<edges.size();i++)  if(edges[i].nocut == 1)printf("%d %d\n",edges[i].from,edges[i].to);printf("#\n");}return 0;}


1 0
原创粉丝点击