zoukankan      html  css  js  c++  java
  • 无向图求割顶双连通分量

    poj1144:

    模板题吧,只是输入的方式真的真的非常非常的蛋疼,看了别人的博客才知道了怎么写○| ̄|_。记住这种写法!!!!!!

     1 #include<cstdio>
     2 #include<vector>
     3 #include<cstring>
     4 #include<iostream>
     5 #include<algorithm>
     6 using namespace std;
     7 #define rep(i,n) for(int i=1;i<=n;i++)
     8 #define clr(x,c) memset(x,c,sizeof(x))
     9 const int nmax=105;
    10 int dfn[nmax],low[nmax],iscut[nmax],n,dfn_clock;
    11 vector<int>f[nmax];
    12 int get(char *ch){
    13     int x=0;
    14     for(int i=0;ch[i];i++)
    15       x=x*10+ch[i]-'0';
    16     return x;
    17 }
    18 int dfs(int u,int fa){
    19     low[u]=dfn[u]=++dfn_clock;
    20     int child=0;
    21     for(int i=0;i<f[u].size();i++){
    22         int v=f[u][i];
    23         if(!dfn[v]){
    24             child++;
    25             dfs(v,u);
    26             low[u]=min(low[u],low[v]);
    27             if(low[v]>=dfn[u])
    28               iscut[u]=1;
    29         }
    30         else if(dfn[v]<dfn[u]&&v!=fa)
    31           low[u]=min(low[u],dfn[v]);
    32     }
    33     if(fa<0&&child==1) iscut[u]=0;
    34     return low[u];
    35 
    36 }
    37 int main(){
    38     while(scanf("%d",&n)&&n){
    39         dfn_clock=0;
    40         clr(dfn,0);clr(iscut,0);
    41         rep(i,n) f[i].clear();
    42         char ch[10];
    43         while(scanf("%s",ch)==1){
    44             if(ch[0]=='0') break;
    45             int u=get(ch);
    46             while(scanf("%s",ch)==1){
    47                 int v=get(ch);
    48                 f[u].push_back(v);
    49                 f[v].push_back(u);
    50                 char t=getchar();
    51                 if(t=='
    ') break;           //就是这里②| ̄|_
    52             }
    53         }
    54         dfs(1,-1);
    55         int ans=0;
    56         rep(i,n)
    57           if(iscut[i])
    58             ans++;
    59         printf("%d
    ",ans);
    60     }
    61     return 0;
    62 }

     poj2117:额没什么难度吧。只是求去掉一个割顶图能得到多少个连通分量。然后在判断的时候弄一下就好了。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<vector>
     4 #include<iostream>
     5 #include<algorithm>
     6 using namespace std;
     7 #define rep(i,n) for(int i=1;i<=n;i++)
     8 #define clr(x,c) memset(x,c,sizeof(x))
     9 const int nmax=10005;
    10 int dfn[nmax],low[nmax],cut[nmax],dfn_clock,n,m;
    11 vector<int>f[nmax];
    12 int read(){
    13     int x=0;
    14     char c=getchar();
    15     while(!isdigit(c)) c=getchar();
    16     while(isdigit(c)){
    17         x=x*10+c-'0';
    18         c=getchar();
    19     }
    20     return x;
    21 }
    22 void dfs(int u,int fa){
    23     low[u]=dfn[u]=++dfn_clock;
    24     for(int i=0;i<f[u].size();i++){
    25         int v=f[u][i];
    26         if(!dfn[v]){
    27             dfs(v,u);
    28             low[u]=min(low[u],low[v]);
    29             if(low[v]>=dfn[u]){
    30                 cut[u]++;
    31             }
    32         }
    33         else if(dfn[v]<=dfn[u]&&v!=fa)
    34           low[u]=min(low[u],dfn[v]);
    35     }
    36 }
    37 int main(){
    38     while(scanf("%d%d",&n,&m)==2&&n){
    39         rep(i,n) f[i].clear();
    40         rep(i,m){
    41             int u=read(),v=read();
    42             u++;
    43             v++;
    44             f[u].push_back(v);
    45             f[v].push_back(u);
    46         }
    47         int ans=dfn_clock=0;
    48         clr(dfn,0);clr(low,0);clr(cut,0);
    49         rep(i,n){
    50             if(!dfn[i]){
    51                 ans++;
    52                 dfs(i,-1);
    53                 cut[i]--;
    54             }
    55         }
    56         int tmp=-2;
    57         rep(i,n)
    58           tmp=max(tmp,cut[i]);
    59         printf("%d
    ",tmp+ans);
    60     }
    61     return 0;
    62 }

     poj3352:

    其实只要对边连通分量熟悉就好了,还有一个公式的应用就好了;

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<vector>
     4 #include<iostream>
     5 #include<algorithm>
     6 using namespace std;
     7 #define rep(i,n) for(int i=1;i<=n;i++)
     8 #define clr(x,c) memset(x,c,sizeof(x))
     9 const int nmax=1005;
    10 vector<int>f[nmax];
    11 int out[nmax],dfn[nmax],low[nmax],n,m,dfn_clock=0;
    12 void dfs(int x,int fa){
    13     dfn[x]=low[x]=++dfn_clock;
    14     for(int i=0;i<f[x].size();i++){
    15         int v=f[x][i];
    16         if(!dfn[v]){
    17             dfs(v,x);
    18             low[x]=min(low[x],low[v]);
    19         }
    20         else if(dfn[v]<dfn[x]&&v!=fa)
    21           low[x]=min(low[x],dfn[v]);
    22     }
    23 }
    24 int main(){
    25     scanf("%d%d",&n,&m);
    26     clr(dfn,0);clr(low,0);clr(out,0);
    27     rep(i,m){
    28         int u,v;
    29         scanf("%d%d",&u,&v);
    30         f[u].push_back(v);
    31         f[v].push_back(u);
    32     };
    33     dfs(1,-1);
    34     rep(i,n){
    35         for(int j=0;j<f[i].size();j++){
    36             int v=f[i][j];
    37             if(low[i]!=low[v])
    38               out[low[v]]++;
    39         }
    40     }
    41     int ans=0;
    42     rep(i,n){
    43         if(out[i]==1)
    44           ans++;
    45     }
    46     printf("%d
    ",(ans+1)/2);
    47     return 0;
    48 
    49 }

     poj3177:

    又是道水题,不过重边判断只能那样低效判断吗○| ̄|_不知道有没有高效一点的方法;果然邻接表跑的比vector好多了;

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 #include<algorithm>
     5 using namespace std;
     6 #define rep(i,n) for(int i=1;i<=n;i++)
     7 #define clr(x,c) memset(x,c,sizeof(x))
     8 struct edge{
     9     int to,next;
    10 }; 
    11 edge e[20005];
    12 int dfn[5004],low[5005],out[5005],h[5005],n,m,dfn_clock=0,map[5005][5005];
    13 int read(){
    14     int x=0;
    15     char c=getchar();
    16     while(!isdigit(c)) c=getchar();
    17     while(isdigit(c)) {
    18         x=x*10+c-'0';
    19         c=getchar();
    20     }
    21     return x;
    22 }
    23 void dfs(int u,int fa){
    24     dfn[u]=low[u]=++dfn_clock;
    25     for(int i=h[u];i;i=e[i].next){
    26         int v=e[i].to;
    27         if(!dfn[v]){
    28             dfs(v,u);
    29             low[u]=min(low[u],low[v]);
    30         }
    31         else if(dfn[v]<dfn[u]&&v!=fa){
    32             low[u]=min(low[u],dfn[v]);
    33         }
    34     }
    35 }
    36 int main(){
    37     n=read();m=read();
    38     int cur=0;
    39     rep(i,m){
    40         int u=read(),v=read();
    41         map[u][v]=map[v][u]=1;
    42     }
    43     rep(i,n)
    44       rep(j,n)
    45         if(map[i][j]){
    46             e[++cur].to=j;
    47             e[cur].next=h[i];
    48             h[i]=cur;
    49         }
    50     dfs(1,-1);
    51     rep(i,n){
    52         for(int j=h[i];j;j=e[j].next){
    53             int tmp=e[j].to;
    54             if(low[i]!=low[tmp]){
    55                 out[low[tmp]]++;
    56             }
    57         }
    58     }
    59     int ans=0;
    60     rep(i,n)
    61       if(out[i]==1)
    62         ans++;
    63     printf("%d
    ",(ans+1)/2);
    64     return 0;
    65 }
  • 相关阅读:
    jQuery的事件处理
    《CSS mastery》 读书笔记
    javascript 基础三
    javascript 基础二
    webpack全局引入jquery的方法
    解决mongoVue的collections不显示问题
    javascript 实现一个回文数字
    nth-child和:nth-of-type的区别
    iscroll5实现一个下拉刷新上拉加载的效果
    js(jquery)解决input元素的blur事件和其他非表单元素的click事件冲突的方法
  • 原文地址:https://www.cnblogs.com/20003238wzc--/p/4851899.html
Copyright © 2011-2022 走看看