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 }
    点双连通
  • 相关阅读:
    putty的复制 技巧
    linux下的yum命令详解
    mysql修改密码
    我的阅读编程书籍的好方法
    WINDOWS下VIM配置
    Debian下VSFTPD配置
    一个远程访问MySQL的错误(2003, 10061)的解决
    auto_increment
    hello,world!
    scss文件中使用深度选择器/deep/报错 Expected selector Jim
  • 原文地址:https://www.cnblogs.com/yijiull/p/7390406.html
Copyright © 2011-2022 走看看