zoukankan      html  css  js  c++  java
  • HDU 3394 Railway —— (点双联通,记录块信息)

      这题是比较模板的找点双联通并记录的题目。

      题意大概是:一个公园有n个景点,1.所有游客都是绕环旅游的,找出所有不在环内的路的条数;2.如果两个环中有重复的边,那么这些边是冲突的,问冲突的边的总数。

      分析:1.即桥的条数;2.找出点双联通分量,在他们内部找重复的边,或者换句话说,找出所有点双联通分量,边数大于点数的,这些边都是冲突的

      那么,什么是点双联通分量呢,就是任意两点都有两条或以上的路径,这些路径的点除了这两点以外,都不相同,或者说,内部无割点,像数字8的形状就不是,8是边双联通;或者再换句话说,任意两边都在一个简单环

      而边双联通图呢,是任意一边都在一个简单环。或者说,所有边都不是桥

      搞清楚这两点就可以了。然后代码都是模板的问题,代码如下:

      1 #include <stdio.h>
      2 #include <algorithm>
      3 #include <string.h>
      4 #include <vector>
      5 #include <stack>
      6 #include <set>
      7 using namespace std;
      8 typedef pair<int,int> pii;
      9 
     10 int n,m;
     11 vector<int> G[10000+5];
     12 int dfn[10000+5],low[10000+5];
     13 int dfs_clock,cnt_qiao,cnt_scc;
     14 vector<pii> block[10000+5];
     15 int vis[10000+5];
     16 stack<pii> S;
     17 
     18 void init()
     19 {
     20     for(int i=0;i<n;i++) G[i].clear();
     21     memset(dfn,0,sizeof(dfn));
     22     dfs_clock=0;
     23     cnt_qiao=0;
     24     cnt_scc=0;
     25     for(int i=0;i<n;i++) block[i].clear();
     26 }
     27 
     28 void dfs(int u,int fa)
     29 {
     30     dfn[u]=low[u]=++dfs_clock;
     31     for(int i=0;i<G[u].size();i++)
     32     {
     33         int v = G[u][i];
     34         if(v==fa) continue;
     35         //S.push(pii(u,v));
     36         //不能在这里push边,不然会出现重边
     37 
     38         if(!dfn[v])   //这是从父到子的访问顺序,只有这个顺序才能判断是不是割点或者桥
     39         {
     40             S.push(pii(u,v));
     41             dfs(v,u);
     42             low[u]=min(low[u],low[v]);
     43 
     44             if(dfn[u]<=low[v]) //这一点是准割点(在根处不成立)
     45             {
     46                 for(;;)
     47                 {
     48                     pii t = S.top();S.pop();
     49                     block[cnt_scc].push_back(t);
     50                     if(t.first==u && t.second==v) break;
     51                 }
     52                 cnt_scc++;
     53             }
     54             if(dfn[u]<low[v]) cnt_qiao++;
     55         }
     56         else if(dfn[v]<dfn[u])    //这是子到父的访问顺序,即反向边
     57         {
     58             S.push(pii(u,v));
     59             low[u]=min(low[u],dfn[v]);
     60         }
     61     }
     62 }
     63 
     64 void solve()
     65 {
     66     for(int i=0;i<n;i++) if(!dfn[i]) dfs(i,-1);
     67 
     68     int cnt=0;
     69 
     70     for(int i=0;i<cnt_scc;i++)
     71     {
     72         memset(vis,0,sizeof(vis));
     73         int cnt_edge = block[i].size();
     74         int cnt_point=0;
     75         for(int j=0;j<block[i].size();j++)
     76         {
     77             pii t = block[i][j];
     78             int u = t.first,v = t.second;
     79             if(!vis[u]) vis[u]=1,cnt_point++;
     80             if(!vis[v]) vis[v]=1,cnt_point++;
     81         }
     82 
     83         if(cnt_point<cnt_edge)
     84         {
     85             cnt+=cnt_edge;
     86         }
     87     }
     88 
     89     printf("%d %d
    ",cnt_qiao,cnt);
     90 }
     91 
     92 int main()
     93 {
     94     while(scanf("%d%d",&n,&m)==2)
     95     {
     96         if(n==0 && m==0) break;
     97         init();
     98 
     99         for(int i=1;i<=m;i++)
    100         {
    101             int u,v;
    102             scanf("%d%d",&u,&v);
    103             G[u].push_back(v);
    104             G[v].push_back(u);
    105         }
    106 
    107         solve();
    108     }
    109     return 0;
    110 }
  • 相关阅读:
    windows系统pycharm终端更改为git bash
    python 连接mysql数据库操作
    selenium 鼠标,键盘操作
    selenium定位,操作元素
    python读取csv,Excel,Txt,Yaml 文件
    Jmeter 学习 搭建(1)
    接口测试
    UnitTest+HTMLTestRunner实战
    HTMLTestRunner.py 文件,已修改完成
    UnitTest + HTMLTestRunner
  • 原文地址:https://www.cnblogs.com/zzyDS/p/5633558.html
Copyright © 2011-2022 走看看