求割点(无向边):

所谓的割点,就是删除某个点,图便不连通了。

 POJ  1523

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int MN=1111;

struct Edge
{
   int to,next;
}edge[MN<<2];

int dfn[MN];
int low[MN];
int head[MN<<2];
int subnet[MN];
int E,tp,root;
int vis[MN];

void Init()
{
    memset(dfn,-1,sizeof(dfn));
    memset(low,0,sizeof(low));
    memset(head,-1,sizeof(head));
    memset(subnet,0,sizeof(subnet));
    memset(vis,0,sizeof(vis));
    E=tp=0;
}

void Add(int a,int b)
{
    edge[E].to=b;
    edge[E].next=head[a];
    head[a]=E++;
}

void tarjan(int u,int fa)
{
    int son=0;
    vis[u]=1;
    dfn[u]=low[u]=++tp;
    for(int i=head[u];i!=-1;i=edge[i].next)
    {
        int v=edge[i].to;
        if(vis[v]==1 && v!=fa)
           low[u]=min(low[u],dfn[v]);
        if(!vis[v])
        {
            tarjan(v,u);
            son++;
            low[u]=min(low[u],low[v]);
            if((u==root && son>1) || (u!=root)&& dfn[u]<=low[v])
              subnet[u]++;
        }
    }
    vis[u]=2;
}
int main()
{
    int i,cas=1,n,a,b,nodes;
    while(scanf("%d",&n) && n)
    {
        nodes=n;
        Init();
        scanf("%d",&b);
        Add(n,b);
        Add(b,n);
        while(scanf("%d",&a) && a)
        {
            scanf("%d",&b);
            if(nodes<a) nodes=a;
            if(nodes<b) nodes=b;
            Add(a,b);
            Add(b,a);
        }
        for(i=1;i<=nodes;i++)
        {
            if(dfn[i]==-1)
            {
                 root=i;
                 tarjan(i,-1);
            }
        }
        int flag=0;
        printf("Network #%d\n",cas++);
        for(i=1;i<=nodes;i++)
        {
            if(subnet[i]>=1)
            {
                flag=1;
                printf("  SPF node %d leaves %d subnets\n",i,subnet[i]+1);
            }
        }
        if(flag==0)  printf("  No SPF nodes\n");
        puts("");
    }
}
View Code

相关文章: