zoukankan      html  css  js  c++  java
  • POJ 1438 One-way Traffic (混合图+边双连通)

    <题目链接>

    题目大意:

    给定一个混合图,问你在能够使得图中所有点能够两两到达的情况下,尽可能多的将无向边变成有向边,输出这些无向边的变化方案。

    解题分析:
    这与之前做过的这道题非常类似 POJ 1515 ,不同的是,本题是混合图。总体的思路还是相同的,就是将无向边定向,但是原图中的桥一定只能是双向的,否则不可能使得所有点两两相互到达,之后就是记录一下无向边定向后的结果即可。

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <iostream>
    using namespace std;
    
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define clr(a,b) memset(a,b,sizeof a)
    const int N = 2e3+5 , M = N*N;
    
    struct Edge{ int to,nxt,fp,cur; }e[M];    //fp表示这是单向边,双向边,或者在原图中不存在,cur用来给这条边定向
    
    int n,m,cnt,tot;
    int head[N],low[N],dfn[N];
    
    inline void init(){
        cnt=tot=0;
        clr(dfn,0);clr(head,-1);clr(low,0);
    }
    
    inline void add(int u,int v,int flag){
        e[cnt]=(Edge){v,head[u],flag,-1};head[u]=cnt++;
    }
    
    void Tarjan(int u,int pre){
        dfn[u]=low[u]=++tot;
        for(int i=head[u];~i;i=e[i].nxt){
            int v=e[i].to;
            if(v==pre)continue;
            if(e[i].cur!=-1)continue;       //如果该边之前已经定过向
            if(!e[i].fp)continue;           //如果改边在原图中不存在
            e[i].cur=1,e[i^1].cur=0;
            if(!dfn[v]){
                Tarjan(v,u);
                low[u]=min(low[u],low[v]);
                if(low[v]>dfn[u])e[i].cur=e[i^1].cur=1;
            }else low[u]=min(low[u],dfn[v]);
        }
    }
    
    int main(){
        while(cin>>n>>m){
            init();
            rep(i,1,m){
                int u,v,c;scanf("%d%d%d",&u,&v,&c);
                if(c==1)add(u,v,1),add(v,u,0);
                else add(u,v,2),add(v,u,2);
            }
            rep(i,1,n) if(!dfn[i]){        
                Tarjan(i,-1);
            }
            //只输出双向边的处理方案
            for(int i=0;i<cnt;i+=2){
                if(e[i].fp==2&&e[i].cur==1&&e[i^1].cur==1)printf("%d %d 2
    ",e[i^1].to,e[i].to);
                else if(e[i].fp==2&&e[i].cur==1&&e[i^1].cur==0)printf("%d %d 1
    ",e[i^1].to,e[i].to);     //e[i]边有效,所以是e[i^1].to--->e[i].to
                else if(e[i].fp==2&&e[i].cur==0&&e[i^1].cur==1)printf("%d %d 1
    ",e[i].to,e[i^1].to);
            }
        }
    }
  • 相关阅读:
    让你一分钟认识电子身份验证系统EID
    jQuery滑动导航菜单
    sql语句中left join、 inner join的使用
    MySQL数据库分表的3种方法
    Apache 配置多端口 多虚拟主机 局域网访问
    8个开发必备的PHP功能(转)
    CentOS&nbsp;6.4&nbsp;图文安装教…
    mysql中char与varchar的区别分析
    PHP+jQuery+Ajax实现用户登录与退…
    隐藏/显示&nbsp;我的电脑盘符驱动…
  • 原文地址:https://www.cnblogs.com/00isok/p/10759937.html
Copyright © 2011-2022 走看看