当前位置:编程学习 > C/C++ >>

codeforces 178B

 


题意:给一个n个点的无向图,m条双向边,保证没有重边和自环,图连通,有q个询问,给两个点,S和T,问从S到T有多少条割边。

思路:看到这题第一反应就是求双连通分量,然后缩点,因为在同一个双连通分量内肯定没有割边,然后缩点后原图就变成了一棵树,因为保证原图连通,所以得到的也只有一颗树,树中的边即为原图中的割边,于是问题就转化成求树中两点的距离了,用LCA即可解决。先贴一个代码。

[cpp] 
#include <iostream>  
#include <string.h>  
#include <stdio.h>  
#include <algorithm>  
#define maxn 100010  
using namespace std; 
struct edge 

    int to; 
    int next; 
    int num; 
}e[3][maxn<<2]; 
int box[3][maxn],cnt[3]; 
void init() 

    memset(box,-1,sizeof(box)); 
    memset(cnt,0,sizeof(cnt)); 

void add(int from,int to,int num,int t) 

    e[t][cnt[t]].to=to; 
    e[t][cnt[t]].num=num; 
    e[t][cnt[t]].next=box[t][from]; 
    box[t][from]=cnt[t]++; 

int pre[maxn]; 
int low[maxn]; 
int bridge[maxn]; 
int bcnt=0; 
int cnt0; 
void bridge_search(int now,int fa) 

    int t; 
    int v,w; 
    low[now]=pre[now]=++cnt0; 
    for(t=box[0][now];t+1;t=e[0][t].next) 
    { 
        v=e[0][t].to; 
        if(v==fa) 
        continue; 
        if(!pre[v]) 
        { 
            bridge_search(v,now); 
            if(low[v]<low[now]) 
            low[now]=low[v]; 
            if(low[v]>pre[now]) 
            { 
                bridge[e[0][t].num]=1; 
            } 
        } 
        else 
        { 
            if(low[now]>pre[v]) 
            low[now]=pre[v]; 
        } 
    } 

int Bridge(int n) 

    int i; 
    cnt0=0; 
    memset(pre,0,sizeof(pre)); 
    memset(low,0,sizeof(low)); 
    memset(bridge,0,sizeof(bridge)); 
    bcnt=0; 
    for(i=1;i<=n;i++) 
    { 
        if(!pre[i]) 
        { 
            bridge_search(i,0); 
        } 
    } 
    return bcnt; 

int vis[maxn]; 
int dist[maxn]; 
void Dfs(int now,int num) 

    low[now]=num; 
    vis[now]=1; 
    int t,v,nn; 
    for(t=box[0][now];t+1;t=e[0][t].next) 
    { 
        v=e[0][t].to,nn=e[0][t].num; 
        if(bridge[nn]) 
        continue; 
        if(!vis[v]) 
        { 
            Dfs(v,num); 
        } 
    } 

void solve(int n)//Ëõµã  

   int i,sum=0; 
   memset(low,0,sizeof(low)); 
   memset(vis,0,sizeof(vis)); 
   for(i=1;i<=n;i++) 
   { 
       if(!low[i]) 
       Dfs(i,++sum); 
   } 
   for(i=1;i<=n;i++) 
   { 
       int t,v; 
       for(t=box[0][i];t+1;t=e[0][t].next) 
       { 
           v=e[0][t].to; 
           if(low[i]!=low[v]) 
           { 
               add(low[i],low[v],0,1); 
               add(low[v],low[i],0,1); 
           } 
       } 
   } 

void dfs(int now,int deep) 

    dist[now]=deep; 
    vis[now]=1; 
    int t,v; 
    for(t=box[1][now];t+1;t=e[1][t].next) 
    { 
        v=e[1][t].to; 
        if(!vis[v]) 
        { 
            dfs(v,deep+1); 
        } 
    } 

int f[maxn]; 
void finit(int n) 

    int i; 
    for(i=0;i<=n;i++) 
    f[i]=i; 

int find(int x) 

    if(x==f[x]) 
    return x; 
    return f[x]=find(f[x]); 

int ans[maxn]; 
void lca(int now) 

    f[now]=now; 
    vis[now]=1; 
    int t,v,x; 
    for(t=box[1][now];t+1;t=e[1][t].next) 
    { 
        v=e[1][t].to; 
        if(!vis[v]) 
        { 
            lca(v); 补充:软件开发 , C++ ,

CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,