SPF(连通图---求割点)

题目链接:SPF

题目大意:给你n条边,问哪条边将网路分成了几个子网络(输出所有的情况)。
思路:给你的是无向图,直接上求割点的模板。

代码:

#include
#include
#include
#include
using namespace std;

const int maxn=2009;
int dfs_clock,DFN[maxn],cut[maxn],low[maxn];
vector<int>g[maxn];
void init()
{
    for(int i=1; i<2000; i++)
        g[i].clear();
    memset(DFN,0,sizeof(DFN));
    memset(cut,0,sizeof(cut));
    memset(low,0,sizeof(low));
    dfs_clock=0;
}
void Trajan(int u,int pre)
{
    low[u]=DFN[u]=++dfs_clock;
    int sum=0;
    for(int i=0; iint v=g[u][i];
        if(v==pre) continue;
        if(!DFN[v])
        {
            Trajan(v,u);
            low[u]=min(low[u],low[v]);
            if(low[v]>=DFN[u])
            {
                sum++;
                if(u!=pre)
                    cut[u]=sum+1;//记录着个点将图分成了几个子图
                else if(sum>1) cut[u]=sum;
            }
        }
        else low[u]=min(low[u],DFN[v]);
    }
}
int main()
{
    int u,v,t=1,flag=0;
    while(~scanf("%d",&u),u)
    {
        init();
        int max_=0;
        scanf("%d",&v);
        max_=max(max_,max(u,v));
        g[u].push_back(v);
        g[v].push_back(u);
        while(~scanf("%d",&u),u)
        {
            scanf("%d",&v);
            max_=max(max_,max(u,v));
            g[u].push_back(v);
            g[v].push_back(u);
        }
        for(int i=1; i<=max_; i++)
        {
            if(!DFN[i])
                Trajan(i,i);
        }
        int sum=1;
        printf("Network #%d\n",t++);
        for(int i=1; i<=max_; i++)
            if(cut[i])
                printf("  SPF node %d leaves %d subnets\n",i,cut[i]),sum=0;
        if(sum)
            printf("  No SPF nodes\n");
        printf("\n");
    }
    return 0;
}

你可能感兴趣的:(ACM,算法,题目,连通图)