• 【求无向图的桥,有重边】ZOJ


    模板题——求割点与桥

    题意,要使一个无向图不连通,输出必定要删掉的边的数量及其编号。求桥的裸题,可拿来练手。

    套模板的时候注意本题两节点之间可能有多条边,而模板是不判重边的,所以直接套模板的话,会将重边也当做桥输出,因此要在判断桥的时候加一个判断,即当且仅当两点之间仅有一条边,且满足dfn[cur] < low[i],(cur, i)才是桥。

    另外本题节点数为105,用邻接矩阵的话会内存超限,所以我用了了一个multiset存储边及其编号。

    代码如下:

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<cstring>
     4 #include<vector>
     5 #include<set>
     6 #include<algorithm>
     7 #include<iostream>
     8 using namespace std;
     9 const int MAX_V = 10005;
    10 const int MAX_E = 100005;
    11 struct Edge
    12 {
    13     int to, id;
    14     Edge() {}
    15     Edge(int _t, int _i):to(_t), id(_i) {}
    16     bool operator < (const Edge& rhs) const
    17     {
    18         return to < rhs.to;
    19     }
    20 };
    21 multiset<Edge> edge[MAX_V];
    22 multiset<int> tms[MAX_V];
    23 vector<int> ans;
    24 int vis[MAX_V]; //结点v当前访问状态,0表示未访问,1表示在栈中,2表示已经访问过
    25 int dfn[MAX_V]; //结点v被访问时的深度
    26 int low[MAX_V]; //结点v可以到达的访问时间最早的祖先的深度
    27 void cut_bridge(int cur, int father, int dep, int n) //vertex: 0~n-1
    28 {
    29     vis[cur] = 1;
    30     dfn[cur] = dep;
    31     low[cur] = dep;
    32     int children = 0;
    33     int sz = edge[cur].size();
    34     for(multiset<Edge>::iterator it = edge[cur].begin(); it != edge[cur].end(); it++)
    35     {
    36         int id = (*it).id;
    37         int i = (*it).to;
    38         if(i != father && vis[i] == 1) //i在当前栈中,说明图中有一个环,用i的深度更新cur的low值;
    39         {
    40             if(dfn[i] < low[cur]) low[cur] = dfn[i]; //将结点cur可以到达的访问时间最早的祖先的深度更新为结点i被访问时的深度;
    41         }
    42         if(vis[i] == 0) //i没被访问过,递归访问节点i,并用i的可以到达的最早祖先来更新cur的low值;
    43         {
    44             cut_bridge(i, cur, dep+1, n);
    45             if(low[i] < low[cur]) low[cur] = low[i];
    46             if(low[i] > dfn[cur] && tms[cur].count(i) == 1)
    47             {
    48                 ans.push_back(id);
    49             }//判断桥
    50         }
    51     }
    52     vis[cur] = 2;
    53 }
    54 void init(int n)
    55 {
    56     ans.clear();
    57     memset(vis, 0, sizeof(vis));
    58     for(int i = 0; i <= n; i++)
    59     {
    60         edge[i].clear();
    61         tms[i].clear();
    62     }
    63 }
    64 int main()
    65 {
    66     int T;
    67     scanf("%d", &T);
    68     for(int kase = 0; kase < T; kase++)
    69     {
    70         if(kase) printf("
    ");
    71         int n, m;
    72         scanf("%d%d", &n, &m);
    73         init(n);
    74         for(int i = 0; i < m; i++)
    75         {
    76             int u, v;
    77             scanf("%d%d", &u, &v);
    78             Edge e1(v, i+1), e2(u, i+1);
    79             edge[u].insert(e1);
    80             edge[v].insert(e2);
    81             tms[u].insert(v);
    82             tms[v].insert(u);
    83         }
    84         for(int i = 1; i <= n; i++)
    85             if(vis[i] == 0)
    86                 cut_bridge(i, -1, 1, n);
    87 
    88         sort(ans.begin(), ans.end());
    89         printf("%d
    ", ans.size());
    90         for(int i = 0; i < ans.size(); i++)
    91         {
    92             if(i) printf(" ");
    93             printf("%d", ans[i]);
    94         }
    95         if(ans.size()) printf("
    ");
    96     }
    97     return 0;
    98 }
    ZOJ 2588
  • 相关阅读:
    内存Fuzz和WinAFL
    AFL分析与实战
    协议Fuzz技术
    Fuzz技术综述与文件Fuzz
    WireShark学习笔记(一)
    虚拟机连接的问题
    jq 时间的代理和父级的删除
    Windows(WSL2) Linux子系统搭建Docker环境
    JavaCV FFmpeg H264编码
    JavaCV FFmpeg AAC编码
  • 原文地址:https://www.cnblogs.com/LLGemini/p/4730961.html
Copyright © 2020-2023  润新知