zoukankan      html  css  js  c++  java
  • HDU 4738 双连通分量 Caocao's Bridges

    求权值最小的桥,考虑几种特殊情况:

    • 图本身不连通,那么就不用派人去了
    • 图的边双连通分量只有一个,答案是-1
    • 桥的最小权值是0,但是也要派一个人过去
      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <algorithm>
      5 #include <vector>
      6 #include <stack>
      7 using namespace std;
      8 
      9 const int maxn = 1000 + 10;
     10 const int maxm = 1000000 + 10;
     11 
     12 int n, m;
     13 
     14 int cc;
     15 int pa[maxn];
     16 int findset(int x) { return x == pa[x] ? x : pa[x] = findset(pa[x]); }
     17 
     18 void Union(int x, int y)
     19 {
     20     int px = findset(x), py = findset(y);
     21     if(px != py) { pa[px] = py; cc--; }
     22 }
     23 
     24 struct Edge
     25 {
     26     int v, nxt, w;
     27 }edges[maxm * 2];
     28 int ecnt;
     29 int head[maxn];
     30 
     31 void AddEdge(int u, int v, int d)
     32 {
     33     edges[ecnt].v = v;
     34     edges[ecnt].w = d;
     35     edges[ecnt].nxt = head[u];
     36     head[u] = ecnt++;
     37 }
     38 
     39 stack<int> S;
     40 bool isbridge[maxm * 2];
     41 int dfs_clock, scc_cnt;
     42 int low[maxn], pre[maxn], sccno[maxn];
     43 
     44 void dfs(int u, int fa)
     45 {
     46     pre[u] = low[u] = ++dfs_clock;
     47     S.push(u);
     48 
     49     for(int i = head[u]; ~i; i = edges[i].nxt)
     50     {
     51         if(i == (fa ^ 1)) continue;
     52         int v = edges[i].v;
     53         if(!pre[v])
     54         {
     55             dfs(v, i);
     56             low[u] = min(low[u], low[v]);
     57             if(low[v] > low[u]) isbridge[i] = true;
     58         }
     59         else if(!sccno[v]) low[u] = min(low[u], pre[v]);
     60     }
     61 
     62     if(low[u] == pre[u])
     63     {
     64         scc_cnt++;
     65         for(;;)
     66         {
     67             int x = S.top(); S.pop();
     68             sccno[x] = scc_cnt;
     69             if(x == u) break;
     70         }
     71     }
     72 }
     73 
     74 void find_scc()
     75 {
     76     dfs_clock = scc_cnt = 0;
     77     memset(isbridge, false, sizeof(isbridge));
     78     memset(pre, 0, sizeof(pre));
     79     memset(sccno, 0, sizeof(sccno));
     80     for(int i = 1; i <= n; i++) if(!pre[i]) dfs(i, -1);
     81 }
     82 
     83 int main()
     84 {
     85     while(scanf("%d%d", &n, &m) == 2 && n)
     86     {
     87         ecnt = 0;
     88         memset(head, -1, sizeof(head));
     89         cc = n;
     90         for(int i = 1; i <= n; i++) pa[i] = i;
     91         while(m--)
     92         {
     93             int u, v, d; scanf("%d%d%d", &u, &v, &d);
     94             Union(u, v);
     95             AddEdge(u, v, d); AddEdge(v, u, d);
     96         }
     97 
     98         if(cc > 1) { puts("0"); continue; }
     99 
    100         find_scc();
    101 
    102         if(scc_cnt == 1) { puts("-1"); continue; }
    103 
    104         int ans = 1000000000;
    105         for(int i = 0; i < ecnt; i += 2) if(isbridge[i]) ans = min(ans, edges[i].w);
    106         if(!ans) ans = 1;
    107         printf("%d
    ", ans);
    108     }
    109 
    110     return 0;
    111 }
    代码君
  • 相关阅读:
    归并排序算法
    交换排序算法
    插入排序算法
    DASCTF2021五月赛
    第二届newsctf
    山西省赛
    2021广东省第一届网络安全竞赛
    2021 DozerCTF
    2021-HSCTF re
    buuctf-re (持续更新)
  • 原文地址:https://www.cnblogs.com/AOQNRMGYXLMV/p/4723261.html
Copyright © 2011-2022 走看看