POJ1515(无向图转强连通图)

B - 双连通
Time Limit:1000MS     Memory Limit:10000KB     64bit IO Format:%I64d & %I64u
Submit   Status

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 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
#


 

题意大概是说把一个无向图转化为有向图,需要取出一些边,(双向变成单向),得到一个有向强连通图,显然,桥不能修改,加个标记就行了。代码如下:

/****************************
* author:crazy_石头
* date:2014/01/18
* algorithm:tarjan
* Pro:亲友团训练-图论1-B
***************************/
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <map>
#include <string>

using namespace std;

#define INF 1<<29
#define eps 1e-8
#define A system("pause")
#define rep(i,h,n) for(int i=(h);i<=(n);i++)
#define ms(a,b) memset((a),(b),sizeof(a))

const int maxn=200020;
const int maxm=20;

struct edge
{
    int from,to,next;
    int iscut;
}e[maxn<<1];
int head[maxn],dfn[maxn],low[maxn],instack[maxn],cnt,index,n,m;

inline void addedge(int u,int v)
{
    e[cnt].from=u;
    e[cnt].to=v;
    e[cnt].next=head[u];
    e[cnt].iscut=-1;
    head[u]=cnt++;
}

inline void tarjan(int u,int f)
{
    low[u]=dfn[u]=++index;
    instack[u]=true;
    for(int i=head[u];~i;i=e[i].next)
    {
        int v=e[i].to;
        if(v==f) continue;
        if(e[i].iscut!=-1)continue;//不为-1说明该边已经修改过了;
        e[i].iscut=1;//修改正向边,去掉反向边;
        e[i^1].iscut=0;
        if(!dfn[v])
        {
            tarjan(v,u);
            low[u]=min(low[u],low[v]);
            if(low[v]>dfn[u])//是桥的条件,则正反向边均可通过,桥是不能修改的;
            {
                e[i].iscut=1;
                e[i^1].iscut=1;
            }
        }
        else if(instack[v])
        low[u]=min(low[u],dfn[v]);
    }
}

inline void init()
{
    ms(head,-1),cnt=0;
}

inline void gao()
{
    index=0;
    ms(low,0),ms(dfn,0),ms(instack,0);
    rep(i,1,n)
    if(!dfn[i]) tarjan(i,-1);
}

inline void solve()
{
    rep(i,0,cnt-1)
        if(e[i].iscut==1)printf("%d %d\n",e[i].from,e[i].to);
}

int main()
{
    int test=1;
    while(~scanf("%d%d",&n,&m),n||m)
    {
        init();
        while(m--)
        {
            int u,v;
            scanf("%d%d",&u,&v);
            addedge(u,v);
            addedge(v,u);
        }
        gao();
        printf("%d\n\n",test++);
        solve();
        printf("#\n");
    }
    return 0;
}


 

 

 

你可能感兴趣的:(POJ1515(无向图转强连通图))