UVA1310 Oneway traffic(图论找桥)

为数不多的没看题解写出来的题....不容易啊我!!不过还是挺兴奋的吧.

题意:给出一个图,有N个点,M条边,边分两种,有单向的,也有无向的,一开始图中任意两点都连通.问你,将尽量多的无向边转换成有向边.

分析:通过画图分析,当仅当无向边是桥的时候,无向边不能转换成有向边,否则就能转换成有向边..故,可以通过求桥来得出答案.但边是无向边时,且不是桥,则将边设置成遍历方向即可!

// File Name: 1310.cpp
// Author: Zlbing
// Created Time: 2013/5/17 14:01:49

#include<iostream>
#include<string>
#include<algorithm>
#include<cstdlib>
#include<cstdio>
#include<set>
#include<map>
#include<vector>
#include<cstring>
#include<stack>
#include<cmath>
#include<queue>
using namespace std;
#define CL(x,v); memset(x,v,sizeof(x));
#define INF 0x3f3f3f3f
#define LL long long
#define REP(i,r,n) for(int i=r;i<=n;i++)
#define RREP(i,n,r) for(int i=n;i>=r;i--)
#define MAXN 2000+5
vector<int>G[MAXN],P[MAXN];
int dfs_clock,bcc_cnt;
int pre[MAXN];
int first2[MAXN];
int T[MAXN];
struct Edge{
    int u,v,flag;
};
vector<Edge> edges;
vector<Edge> A;
int dfs1(int u,int fa)
{
    int lowu=pre[u]=++dfs_clock;
    for(int i=0;i<G[u].size();i++)
    {
        int mm=G[u][i];
        int v=edges[mm].v;
        if(!pre[v])
        {
        //    printf("u--%d v=%d\n",u,v);
            int lowv=dfs1(v,u);
            lowu=min(lowu,lowv);
            if(lowv>pre[u])
            {
            //    printf("22222u--%d v=%d\n",u,v);
                A.push_back((Edge){edges[mm].u,edges[mm].v,2});
            }
            else if(edges[mm].flag==2){
                //printf("111111u--%d v=%d\n",u,v);
                A.push_back((Edge){edges[mm].u,edges[mm].v,1});
            }
        }
        else if(pre[v]<pre[u]&&v!=fa)
        {
            lowu=min(pre[v],lowu);
            if(edges[mm].flag==2)
            A.push_back((Edge){edges[mm].u,edges[mm].v,1});
        }
    }
    return lowu;
}
void find_bcc(int n)
{
    dfs_clock=0,bcc_cnt=0;
    memset(pre,0,sizeof(pre));
    for(int i=1;i<=n;i++)
        if(!pre[i])
            dfs1(i,-1);
}

int n,m;
int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        int a,b,c;
        REP(i,0,n)
        {
            G[i].clear();
            P[i].clear();
        }
        edges.clear();
        A.clear();
        REP(i,1,m)
        {
            scanf("%d%d%d",&a,&b,&c);
            edges.push_back((Edge){a,b,c});

            if(c==2)
            edges.push_back((Edge){b,a,c});
            int mm=edges.size();
            if(c==1)
            {
                G[a].push_back(mm-1);
            }
            else{
                G[a].push_back(mm-2);
                G[b].push_back(mm-1);
            }
        }
//        for(int i=0;i<edges.size();i++)
//            printf("u==%d v==%d flag=%d\n",edges[i].u,edges[i].v,edges[i].flag);
        find_bcc(n);
        for(int i=0;i<A.size();i++)
        {
            printf("%d %d %d\n",A[i].u,A[i].v,A[i].flag);
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/arbitrary/p/3083703.html