zoukankan      html  css  js  c++  java
  • [USACO06JAN]Redundant Paths

    OJ题号:
    洛谷2860、POJ3177

    题目大意:
    给定一个无向图,试添加最少的边使得原图中没有桥。

    思路:
    Tarjan缩点,然后统计度为$1$的连通分量的个数(找出原图中所有的桥)。
    考虑给它们每两个连通分量连一条边,这样一次性可以解决两个。
    如果最后还有多的,就专门给它随便连一条边。
    设度为$1$的连通分量的个数为$c$,则答案为$lfloor{frac{c+1}{2}} floor$。
    因为是无向图,所以用一般的Tarjan会来回走同一条边,这样就会把桥的两岸缩在同一个点中,不合题意。
    考虑Tarjan中记录当前结点的父亲结点,往下递归时判断是否与其相等。这样看起来是正确的,但是交到洛谷上会WA一个点。
    因为原图中不一定保证相同的两个点之间只有一条边,因此如果当某两点间同时存在两条边时,不能算桥。但是按照上面的算法不会将这两点缩在一起。
    考虑记录每条边的编号,每次递归判断枚举到的出边是否与入边编号相等即可。

     1 #include<stack>
     2 #include<cstdio>
     3 #include<cctype>
     4 #include<vector>
     5 inline int getint() {
     6     char ch;
     7     while(!isdigit(ch=getchar()));
     8     int x=ch^'0';
     9     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
    10     return x;
    11 }
    12 const int V=5001;
    13 struct Edge {
    14     int to,id;
    15 };
    16 std::vector<Edge> e[V];
    17 inline void add_edge(const int u,const int v,const int id) {
    18     e[u].push_back((Edge){v,id});
    19 }
    20 int dfn[V]={0},low[V]={0},scc[V]={0},cnt=0,id=0;
    21 bool ins[V]={0};
    22 std::stack<int> s;
    23 void Tarjan(const int x,const int eid) {
    24     dfn[x]=low[x]=++cnt;
    25     s.push(x);
    26     ins[x]=true;
    27     for(unsigned i=0;i<e[x].size();i++) {
    28         if(e[x][i].id==eid) continue;
    29         int &y=e[x][i].to;
    30         if(!dfn[y]) {
    31             Tarjan(y,e[x][i].id);
    32             low[x]=std::min(low[x],low[y]);
    33         }
    34         else if(ins[y]) {
    35             low[x]=std::min(low[x],dfn[y]);
    36         }
    37     }
    38     if(low[x]==dfn[x]) {
    39         int y;
    40         id++;
    41         do {
    42             y=s.top();
    43             s.pop();
    44             ins[y]=false;
    45             scc[y]=id;
    46         } while(y!=x);
    47     }
    48 }
    49 int deg[V]={0};
    50 int main() {
    51     int n=getint();
    52     for(int m=getint();m;m--) {
    53         int u=getint(),v=getint();
    54         add_edge(u,v,m);
    55         add_edge(v,u,m);
    56     }
    57     for(int i=1;i<=n;i++) {
    58         if(!dfn[i]) Tarjan(i,0);
    59     }
    60     for(int x=1;x<=n;x++) {
    61         for(unsigned i=0;i<e[x].size();i++) {
    62             int &y=e[x][i].to;
    63             if(scc[x]!=scc[y]) deg[scc[x]]++,deg[scc[y]]++;
    64         }
    65     }
    66     int cnt=0;
    67     for(int i=1;i<=id;i++) {
    68         if(deg[i]==2) cnt++;
    69     }
    70     printf("%d
    ",(cnt+1)>>1);
    71     return 0;
    72 } 
  • 相关阅读:
    大数据学习之sqoop框架 25
    大数据学习之Flume框架 24
    大数据学习之Hive UDF及优化23
    大数据学习之HiveDDM数据操作语言22
    大数据学习之Hive数据仓库DDL数据定义语言21
    【MacOs】 SecureCRT设置linux终端显示颜色
    【MacOs】 VMware Fusion的NAT端口映射+静态IP
    【nginx】测试服务器配置内网项目转发
    【Linux】SSH连接linux时,长时间不操作就断开的解决方案
    【PHP】简易系统环境控制
  • 原文地址:https://www.cnblogs.com/skylee03/p/7429616.html
Copyright © 2011-2022 走看看