poj 1523 SPF

http://poj.org/problem?id=1523

题目大意:给定一个图,求这个图的割点,以及把该割点去掉以后的图有多少过连通分量。

思路:先求出所有的割点,然后暴力枚举这些割点求连通分量(1000个点)。

View Code
#include<set>
#include<map>
#include<stack>
#include<queue>
#include<cmath>
#include<bitset>
#include<string>
#include<climits>
#include<cstdio>
#include<vector>
#include<utility>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define IN puts("in")
#define OUT puts("out")
#define FR(x) freopen(x,"r",stdin)
#define FW(x) freopen(x,"w",stdout)
#define ST system("pause")
using namespace std;

const int maxn = 1005;

struct nd
{
        int u,v,next;
}edge[maxn*1000];
int head[maxn],vis[maxn],dfn[maxn],low[maxn],gone[maxn];
int ecnt,cnt,idx,tot,n,cas;
void add(int u,int v)
{
        edge[ecnt].u = u;
        edge[ecnt].v = v;
        edge[ecnt].next = head[u];
        head[u] = ecnt++;
}
void tarjan(int pre,int u)
{
        int i,v;
        dfn[u] = low[u] = ++idx;
        for(i = head[u]; i != -1; i = edge[i].next)
        {
                v = edge[i].v;
                if(v==pre)continue;
                if(!dfn[v]){
                        tarjan(u,v);
                        low[u] = min(low[v],low[u]);
                        if(low[v]>=low[u]) vis[u] = 1;
                }else low[u] = min(dfn[v],low[u]);
        }
}
void dfs(int pre,int u)
{
        int i,v;
        if(gone[u]||pre==u)return;
        gone[u] = 1;
        for(i = head[u]; i != -1; i = edge[i].next) dfs(u,edge[i].v);
}
int sovle()
{
        int i,j,k,u,v,flag = 0;
        scanf("%d",&u);
        if(!u)return 0;
        printf("Network #%d\n",++cas);
        n = 0;
        memset(vis,0,sizeof(vis));
        memset(dfn,0,sizeof(dfn));
        memset(low,0,sizeof(low));
        memset(head,-1,sizeof(head));
        ecnt = cnt = idx = 0;
        do{
                scanf("%d",&v);
                n = max(n,max(u,v));
                add(u,v); add(v,u);
                scanf("%d",&u);
        }while(u);
        for(i = 1; i <= n; ++ i)
                if(!dfn[i])tarjan(-1,i);
        for(i = 1; i <= n; ++ i)
                if(vis[i]){
                        tot = 0;
                        memset(gone,0,sizeof(gone));
                        gone[i] = 1;
                        for(j = head[i]; j != -1; j = edge[j].next)
                                if(!gone[edge[j].v]){
                                        tot++;
                                        dfs(-1,edge[j].v);
                                }
                        if(tot>1){printf("  SPF node %d leaves %d subnets\n",i,tot); flag = 1;}
                }
        if(!flag)puts("  No SPF nodes");
        return 1;
}
int main()
{
        while(1){if(cas)puts("");if(sovle()==0)break;}
        return 0;
}

posted on 2012-07-03 20:39  aigoruan  阅读(148)  评论(0)    收藏  举报

导航