程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> codeforces 178B

codeforces 178B

編輯:C++入門知識

 


題意:給一個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); 
            f[v]=now; 
        } 
    } 
    for(t=box[2][now];t+1;t=e[2][t].next) 
    { 
        v=e[2][t].to,x=e[2][t].num; 
        if(vis[v]==2) 
        { 
            int tt=find(v); 
            ans[x]=dist[now]+dist[v]-2*dist[tt]; 
        } 
    } 
    vis[now]=2; 

int main() 

    //freopen("dd.txt","r",stdin);  
    int n,m,i,a,b,q; 
    scanf("%d%d",&n,&m); 
    init(); 
    for(i=1;i<=m;i++) 
    { 
        scanf("%d%d",&a,&b); 
        add(a,b,i,0); 
        add(b,a,i,0); 
    } 
    memset(ans,0,sizeof(ans)); 
    Bridge(n); 
    solve(n); 
    memset(vis,0,sizeof(vis)); 
    dfs(1,0); 
    scanf("%d",&q); 
    for(i=1;i<=q;i++) 
    { 
        scanf("%d%d",&a,&b); 
        if(low[a]!=low[b]) 
        { 
            add(low[a],low[b],i,2); 
            add(low[b],low[a],i,2); 
        } 
    } 
    memset(vis,0,sizeof(vis)); 
    lca(1); 
    for(i=1;i<=q;i++) 
    printf("%d\n",ans[i]); 
    return 0; 

#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);
            f[v]=now;
        }
    }
    for(t=box[2][now];t+1;t=e[2][t].next)
    {
        v=e[2][t].to,x=e[2][t].num;
        if(vis[v]==2)
        {
            int tt=find(v);
            ans[x]=dist[now]+dist[v]-2*dist[tt];
        }
    }
    vis[now]=2;
}
int main()
{
    //freopen("dd.txt","r",stdin);
    int n,m,i,a,b,q;
    scanf("%d%d",&n,&m);
    init();
    for(i=1;i<=m;i++)
    {
        scanf("%d%d",&a,&b);
        add(a,b,i,0);
        add(b,a,i,0);
    }
    memset(ans,0,sizeof(ans));
    Bridge(n);
    solve(n);
    memset(vis,0,sizeof(vis));
    dfs(1,0);
    scanf("%d",&q);
    for(i=1;i<=q;i++)
    {
        scanf("%d%d",&a,&b);
        if(low[a]!=low[b])
        {
            add(low[a],low[b],i,2);
            add(low[b],low[a],i,2);
        }
    }
    memset(vis,0,sizeof(vis));
    lca(1);
    for(i=1;i<=q;i++)
    printf("%d\n",ans[i]);
    return 0;
}

 

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved