zoukankan      html  css  js  c++  java
  • 图论:桥

    UVA796:利用Tarjan求无向图的割边(桥)

    Tarjan求割边和求割点的差异不大

    int n,deep,root,cnt;
    int g[maxn],dfn[maxn],low[maxn];
    struct Edge{int t,w,next;}e[maxm];
    map<int,map<int,int> > mp;
    vector<pair<int,int> > bridge;

    这里有的变量在上一篇博文中已经介绍过了

    我们看到mp映射是用来替代二维数组进行判重的

    本来打算换成hash_map但是发现并不好用,这是个必须要补的坑

    这里的判重是判断是否有重边,由于权重都是1所以并不需要进行更新边权

    由于是使用的邻接表来存的图,所以判重不是很方便

    可以先读成邻接矩阵再转存邻接表

    bridge就是我们求出来的所有的桥

    int tarjan(int u,int fa)
    {
        int lowu;
        lowu=dfn[u]=++deep;
        for(int tmp=g[u];tmp;tmp=e[tmp].next)
        {
            int v=e[tmp].t;
            if(!dfn[v])
            {
                int lowv=tarjan(v,u);
                lowu=min(lowu,lowv);
                if(lowv>dfn[u])
                {
                    int from,to;from=u;to=v;
                    if(from>to) swap(from,to);
                    bridge.push_back(make_pair(from,to));
                }
            }
            else if(v!=fa&&dfn[v]<dfn[u])
                lowu=min(lowu,dfn[v]);
        }
        low[u]=lowu;
        return lowu;
    }
    int tarjan(int u,int fa)
    {
        int lowu;
        lowu=dfn[u]=++deep;
        for(int tmp=g[u];tmp;tmp=e[tmp].next)
        {
            int v=e[tmp].t;
            if(!dfn[v])
            {
                int lowv=tarjan(v,u);
                lowu=min(lowu,lowv);
                if(lowv>dfn[u])
                {
                    int from,to;from=u;to=v;
                    if(from>to) swap(from,to);
                    bridge.push_back(make_pair(from,to));
                }
            }
            else if(v!=fa&&dfn[v]<dfn[u])
                lowu=min(lowu,dfn[v]);
        }
        low[u]=lowu;
        return lowu;
    }
    int tarjan(int u,int fa)
    {
        int lowu;
        lowu=dfn[u]=++deep;
        for(int tmp=g[u];tmp;tmp=e[tmp].next)
        {
            int v=e[tmp].t;
            if(!dfn[v])
            {
                int lowv=tarjan(v,u);
                lowu=min(lowu,lowv);
                if(lowv>dfn[u])
                {
                    int from,to;from=u;to=v;
                    if(from>to) swap(from,to);
                    bridge.push_back(make_pair(from,to));
                }
            }
            else if(v!=fa&&dfn[v]<dfn[u])
                lowu=min(lowu,dfn[v]);
        }
        low[u]=lowu;
        return lowu;
    }

    以上是求割边的Tarjan

    最后给出完整实现,题目说了要排序,那就排序吧。把求出来的桥排序

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<vector>
     4 #include<map>
     5 #include<algorithm>
     6 using namespace std;
     7 const int maxn=10005;
     8 const int maxm=100005;
     9 int n,deep,root,cnt;
    10 int g[maxn],dfn[maxn],low[maxn];
    11 struct Edge{int t,w,next;}e[maxm];
    12 map<int,map<int,int> > mp;
    13 vector<pair<int,int> > bridge;
    14 bool cmp(pair<int,int> x,pair<int,int> y)
    15 {
    16     if(x.first!=y.first)
    17         return  x.first<y.first;
    18     else return x.second<y.second;
    19 }
    20 void addedge(int u,int v,int w)
    21 {
    22     if(mp[u][v]==1) return;
    23     else {mp[u][v]=1;}  
    24     e[++cnt].t=v;e[cnt].w=w;
    25     e[cnt].next=g[u];g[u]=cnt;
    26 }
    27 int tarjan(int u,int fa)
    28 {
    29     int lowu;
    30     lowu=dfn[u]=++deep;
    31     for(int tmp=g[u];tmp;tmp=e[tmp].next)
    32     {
    33         int v=e[tmp].t;
    34         if(!dfn[v])
    35         {
    36             int lowv=tarjan(v,u);
    37             lowu=min(lowu,lowv);
    38             if(lowv>dfn[u])
    39             {
    40                 int from,to;from=u;to=v;
    41                 if(from>to) swap(from,to);
    42                 bridge.push_back(make_pair(from,to));
    43             }
    44         }
    45         else if(v!=fa&&dfn[v]<dfn[u])
    46             lowu=min(lowu,dfn[v]);
    47     }
    48     low[u]=lowu;
    49     return lowu;
    50 }
    51 int main()
    52 {
    53     while(scanf("%d",&n)==1)
    54     {
    55         deep=cnt=0;
    56         memset(g,0,sizeof(g));
    57         memset(dfn,0,sizeof(dfn));
    58         memset(low,0,sizeof(low));
    59         memset(e,0,sizeof(e));
    60         mp.clear();
    61         bridge.clear();
    62         int u,v,m;
    63         for(int i=1;i<=n;i++)
    64         {
    65             scanf("%d (%d)",&u,&m);
    66             for(int j=1;j<=m;j++)
    67                 scanf("%d",&v),addedge(u,v,1);
    68         }
    69         for(int i=1;i<=n;i++)
    70             if(!dfn[i]) {root=i;tarjan(i,-1);}
    71         printf("%d critical links
    ",bridge.size());
    72         sort(bridge.begin(),bridge.end(),cmp);
    73         for(int i=0;i<bridge.size();i++)
    74             printf("%d - %d
    ",bridge[i].first,bridge[i].second);
    75         printf("
    ");
    76     }
    77     return 0;
    78 }
  • 相关阅读:
    王爽汇编实验(八)
    王爽汇编实验(七)
    王爽汇编实验(六)
    王爽汇编实验(五)
    计算机操作系统锁机制.
    网页搜索框里显示字段鼠标点击后就隐藏的方法
    织梦删掉会员空间,保留开放会员(禁止注册)的方法
    织梦DEDECMS后台验证码错误不能正常验证的3种可能原因和解决
    织梦DEDECMS后台验证码错误不能正常验证的3种可能原因和解决
    织梦怎么对某些字段信息隐藏,登录后可查看
  • 原文地址:https://www.cnblogs.com/aininot260/p/9428605.html
Copyright © 2011-2022 走看看