传送门
题目大意:求出每一个割点能将图分成几个部分。

思路:乱搞O(∩_∩)O(遇见割点,在对应的数组里加1就行了),但是要注意输出格式很坑,每次要多输出一个空行。

#include<cstdio>
#include<cstring>
#define min(a,b) (a)<(b)?(a):(b)
#define MAXN 5005
#define MAXM 20005
struct node
{
    int v;
    node *next;
} Edge[MAXM], *Adj[MAXN], *Mcnt = Edge;
void addedge(int u, int v)
{
    node *t = ++Mcnt;
    t->v = v;
    t->next = Adj[u];
    Adj[u] = t;
}
int dfn[MAXN], low[MAXN], cnt, rtson;
int isc[MAXN]; // 表示去掉某个点能将图分成几部分
void dfs(int u, int fa)
{
    dfn[u] = low[u] = ++cnt;
    int son = 0;
    for(node *p = Adj[u]; p; p = p->next)
    {
        if(!dfn[p->v])
        {
            dfs(p->v, u);
            low[u] = min(low[u],low[p->v]);
            if(low[p->v] >= dfn[u] && fa != -1) ++isc[u];
            son++;
        }
        else if(p->v != fa)low[u] = min(low[u], dfn[p->v]);
    }
    if(fa == -1 && son > 1) rtson = son;
}
int main()
{
    int t1, t2;
    int Cas = 0;
    while(~scanf("%d", &t1))
    {
        ++Cas;
        if(t1 == 0)return 0;
        scanf("%d", &t2);
        memset(Adj, 0, sizeof Adj);
        memset(isc, 0, sizeof isc);
        memset(dfn, 0, sizeof dfn);
        memset(low, 0, sizeof low);
        Mcnt = Edge;
        cnt = 0;
        rtson = 0;
        addedge(t1, t2);
        addedge(t2, t1);
        while(~scanf("%d", &t1))
        {
            if(t1 == 0) break;
            scanf("%d", &t2);
            addedge(t1, t2);
            addedge(t2, t1);
        }
        dfs(1, -1);
        bool flag = 1;
        printf("Network #%d\n",Cas);
        if(rtson>1) isc[1] = rtson;
        for(int i = 1; i <= cnt; i++)
            if(isc[i])
            {
                printf("  SPF node %d leaves %d subnets\n", i, isc[i] + (i != 1)); //因为若不是根节点,除了能分出几个子树外,还留下了一块
                flag = 0;
            }
        if(flag)
            puts("  No SPF nodes");
        putchar('\n');
    }
    return 0;
}
posted on 2015-07-20 13:51  geng4512  阅读(132)  评论(0)    收藏  举报