poj1523割顶-点双联通

Posted walfy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了poj1523割顶-点双联通相关的知识,希望对你有一定的参考价值。

题意:求出所有的割顶,而且还有输出该割顶连接了几个点双连通分量

题解:直接tarjan求点双联通分量就好了,可以在加入边的时候记录加入次数,大于1的都是桥,输入输出很恶心,注意格式

技术分享
#include<map>
#include<set>
#include<list>
#include<cmath>
#include<queue>
#include<stack>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define pii pair<int,int>
#define C 0.5772156649
#define pi acos(-1.0)
#define ll long long
#define mod 1000000007
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1

using namespace std;
using namespace __gnu_cxx;

const double g=10.0,eps=1e-7;
const int N=1000+10,maxn=100000+10,inf=0x3f3f3f;

map<int,int>ma[N];
vector<int>v[N],bcc[N];
int dfn[N],low[N];
int index,num;
int bccno[N],iscut[N];
struct edge{int from,to;};
stack<edge>s;
void tarjan(int u,int f)
{
    low[u]=dfn[u]=++index;
    for(int i=0;i<v[u].size();i++)
    {
        int x=v[u][i];
        edge e=(edge){u,x};
        if(x==f)continue;
        if(!dfn[x])
        {
            s.push(e);
            tarjan(x,u);
            low[u]=min(low[u],low[x]);
            if(low[x]>=dfn[u])
            {
                num++;bcc[num].clear();
                for(;;)
                {
                    edge p=s.top();s.pop();
                    if(bccno[p.from]!=num)
                    {
                        bccno[p.from]=num;
                        bcc[num].pb(p.from);
                        iscut[p.from]++;
                    }
                    if(bccno[p.to]!=num)
                    {
                        bccno[p.to]=num;
                        bcc[num].pb(p.to);
                        iscut[p.to]++;
                    }
                    if(p.from==e.from&&p.to==e.to)break;
                }
            }
        }
        else
        {
            if(dfn[x]<dfn[u])low[u]=min(low[u],dfn[x]);
        }
    }
}
void init()
{
    memset(dfn,0,sizeof dfn);
    memset(low,0,sizeof low);
    memset(bccno,0,sizeof bccno);
    memset(iscut,0,sizeof iscut);
    index=num=0;
    for(int i=1;i<=1000;i++)
    {
        v[i].clear();
        bcc[i].clear();
        ma[i].clear();
    }
    while(!s.empty())s.pop();
}
int main()
{
    int a,b,n=0,cnt=0;
    while(~scanf("%d",&a))
    {
        if(a==0)break;
        init();
        scanf("%d",&b);
        n=max(n,max(a,b));
        v[a].pb(b);
        v[b].pb(a);
        ma[a][b]=ma[b][a]=1;
        while(~scanf("%d",&a))
        {
            if(a==0)break;
            scanf("%d",&b);
            n=max(n,max(a,b));
            if(!ma[a][b])
            {
                v[a].pb(b);
                v[b].pb(a);
                ma[a][b]=ma[b][a]=1;
            }
        }
        for(int i=1;i<=n;i++)
            if(!dfn[i])
                tarjan(i,-1);
      /*  cout<<num<<endl;
        for(int i=1;i<=num;i++)
        {
            for(int j=0;j<bcc[i].size();j++)
                cout<<bcc[i][j]<<" ";
            cout<<endl;
        }*/
        printf("Network #%d\n",++cnt);
        bool ok=0;
        for(int i=1;i<=n;i++)
        {
            if(iscut[i]>1)
            {
                ok=1;
                printf("  SPF node %d leaves %d subnets\n",i,iscut[i]);
            }
        }
        if(!ok)printf("  No SPF nodes\n");
puts("");
    }
    return 0;
}
/************

************/
View Code

 

以上是关于poj1523割顶-点双联通的主要内容,如果未能解决你的问题,请参考以下文章

poj2942 点-双联通+二分图染色

POJ 3694Network(Tarjan边双联通分量 + 缩点 + LCA并查集维护)

POJ 3177 Redundant Paths 无向图边双联通基础题

POJ 1515 双联通分量

无向图的双联通分量

poj-3177(并查集+双联通分量+Tarjan算法)