zoukankan      html  css  js  c++  java
  • Railway HDU

    Railway

     HDU - 3394 

    题意:一个无向图,1求不在任何一个环里的边数;2求在不止一个环里的边数。

    第一问明显就是求桥,第二问,如果求出的某个点双连通分量里面边数多于点数,说明不止一个环,那么所有的边都在不止一个环里。

    该求点双连通的,,求成了边双连通。。。要仔细分析问题。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <vector>
     5 using namespace std;
     6 const int maxv=10010;
     7 int n,m;
     8 int ans1,ans2;
     9 struct Edge{
    10     int u,v,nex;
    11     bool iscut;
    12 }e[100010<<1];
    13 int head[maxv];
    14 int cnt;
    15 void init(){
    16     memset(head,-1,sizeof(head));
    17     cnt=0;
    18 }
    19 void add(int u,int v){
    20     e[cnt].u=u;
    21     e[cnt].iscut=0;
    22     e[cnt].v=v;
    23     e[cnt].nex=head[u];
    24     head[u]=cnt++;
    25 }
    26 int pre[maxv],bccno[maxv],dfsk,bcc_cnt;
    27 int vis[maxv];
    28 vector<int> bcc[maxv];
    29 
    30 int dfs(int u,int id){
    31     int lowu=pre[u]=++dfsk;
    32     for(int i=head[u];i!=-1;i=e[i].nex){
    33         int v=e[i].v;
    34         if(i==(id^1)) continue;
    35         if(!pre[v]){
    36             int lowv=dfs(v,i);
    37             lowu=min(lowu,lowv);
    38             if(lowv>pre[u]) e[i].iscut=e[i^1].iscut=1,ans1++;
    39         }
    40         else lowu=min(lowu,pre[v]);
    41     }
    42     return lowu;
    43 }
    44 void dfs1(int u){
    45     bccno[u]=bcc_cnt;
    46     vis[u]=1;
    47     for(int i=head[u];i!=-1;i=e[i].nex){
    48         if(e[i].iscut) continue;
    49         bcc[bcc_cnt].push_back(i);
    50         int v=e[i].v;
    51         if(!vis[v]) dfs1(v);
    52     }
    53 }
    54 
    55 void find_bcc(int n){
    56     memset(pre,0,sizeof(pre));
    57     memset(vis,0,sizeof(vis));
    58     memset(bccno,0,sizeof(bccno));
    59     dfsk=bcc_cnt=0;
    60     for(int i=0;i<n;i++) if(!pre[i]) dfs(i,-1);
    61     for(int i=0;i<n;i++) if(!vis[i]){
    62         bcc_cnt++;
    63         bcc[bcc_cnt].clear();
    64         dfs1(i);
    65     }
    66 }
    67 int main(){
    68        while(scanf("%d%d",&n,&m)&&(n||m)){
    69            init();
    70            ans1=ans2=0;
    71            int u,v;
    72            for(int i=0;i<m;i++){
    73                scanf("%d%d",&u,&v);
    74                add(u,v);
    75                add(v,u);
    76            }
    77            find_bcc(n);
    78 
    79            for(int i=1;i<=bcc_cnt;i++){
    80                 int temp=0;
    81                 memset(vis,0,sizeof(vis));
    82              //   cout<<bcc[i].size()<<endl;
    83                 for(int j=0;j<bcc[i].size();j++){
    84                  //   printf("---%d---
    ",bcc[i][j]);
    85                     Edge p=e[bcc[i][j]];
    86                     if(!vis[p.u]) {vis[p.u]=1;temp++;}
    87                     if(!vis[p.v]) {vis[p.v]=1;temp++;}
    88                 }
    89                 if(temp<bcc[i].size()/2) ans2+=bcc[i].size()/2;
    90            }
    91            printf("%d %d
    ",ans1,ans2);
    92        }
    93 }
    边双连通=_=
      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <vector>
      5 #include <stack>
      6 using namespace std;
      7 const int maxv=10010;
      8 int n,m;
      9 int ans1,ans2;
     10 struct Edge
     11 {
     12     int u,v,nex;
     13 }e[100010<<1];
     14 int head[maxv];
     15 int cnt;
     16 void init()
     17 {
     18     memset(head,-1,sizeof(head));
     19     cnt=0;
     20 }
     21 void add(int u,int v)
     22 {
     23     e[cnt].u=u;
     24     e[cnt].v=v;
     25     e[cnt].nex=head[u];
     26     head[u]=cnt++;
     27 }
     28 int pre[maxv],bccno[maxv],dfsk,bcc_cnt;
     29 stack <int> s;  //存的是边的标号
     30 vector<int> bcc[maxv];  //存的是边的标号
     31 int vis[maxv];
     32 
     33 int dfs(int u,int id){
     34     int lowu=pre[u]=++dfsk;
     35     for(int i=head[u];i!=-1;i=e[i].nex){
     36         int v=e[i].v;
     37         if(i==(id^1)) continue;
     38         if(!pre[v]){
     39             s.push(i);
     40             int lowv=dfs(v,i);
     41             lowu=min(lowu,lowv);
     42             if(lowv>pre[u]) ans1++;  //割边
     43             if(lowv>=pre[u]){
     44                 bcc_cnt++;
     45                 bcc[bcc_cnt].clear();
     46                 for(;;){
     47                     int p=s.top();
     48                     s.pop();
     49                     bcc[bcc_cnt].push_back(p);
     50                     if(p==i) break;
     51                 }
     52             }
     53         }
     54         else if(pre[v]<pre[u]){
     55             s.push(i);
     56             lowu=min(lowu,pre[v]);
     57         }
     58     }
     59     return lowu;
     60 }
     61 
     62 void find_bcc(int n){
     63     memset(pre,0,sizeof(pre));
     64     memset(bccno,0,sizeof(bccno));
     65     dfsk=bcc_cnt=0;
     66     for(int i=0;i<n;i++) if(!pre[i]) dfs(i,-1);
     67 }
     68 
     69 int main(){
     70        while(scanf("%d%d",&n,&m)&&(n||m)){
     71            init();
     72            ans1=ans2=0;
     73            int u,v;
     74            for(int i=0;i<m;i++){
     75                scanf("%d%d",&u,&v);
     76                add(u,v);
     77                add(v,u);
     78            }
     79            find_bcc(n);
     80 
     81            for(int i=1;i<=bcc_cnt;i++){
     82                 int temp=0;
     83                 memset(vis,0,sizeof(vis));
     84                 for(int j=0;j<bcc[i].size();j++){
     85                     Edge p=e[bcc[i][j]];
     86                     if(!vis[p.u]) {vis[p.u]=1;temp++;}
     87                     if(!vis[p.v]) {vis[p.v]=1;temp++;}
     88                 }
     89                 if(temp<bcc[i].size()) ans2+=bcc[i].size();
     90            }
     91            printf("%d %d
    ",ans1,ans2);
     92         /*
     93         //输出边的顺序看一下挺好的,深入了解前向星工作方式
     94            for(int i=1;i<=bcc_cnt;i++)
     95             {
     96                 for(int j=0;j<bcc[i].size();j++)
     97                     cout<<bcc[i][j]<<" ";
     98                 cout<<endl;
     99             }  
    100                 
    101         */ 
    102        }
    103 }
    点双连通
  • 相关阅读:
    20200226 Java IO流——廖雪峰
    20200225 Java 多线程(2)-廖雪峰
    20200225 Java 多线程(1)-廖雪峰
    20200224 尚硅谷ElasticSearch【归档】
    20200224 一 概述
    20200222 尚硅谷Dubbo【归档】
    20200222 四、dubbo原理
    Improved robustness of reinforcement learning policies upon conversion to spiking neuronal network platforms applied to Atari Breakout game
    Reinforcement learning in populations of spiking neurons
    Solving the Distal Reward Problem through Linkage of STDP and Dopamine Signaling
  • 原文地址:https://www.cnblogs.com/yijiull/p/7390406.html
Copyright © 2011-2022 走看看