uva315 Network 【tarjan-求割點】

                                **uva Network**

Description
A Telephone Line Company (TLC) is establishing a new telephone cable network. They are connecting
several places numbered by integers from 1 to N. No two places have the same number. The lines are bidirectional and always connect together two places and in each place the lines end in a telephone exchange. There is one telephone exchange in each place. From each place it is possible to reach through lines every other place, however it need not be a direct connection, it can go through several exchanges. From time to time the power supply fails at a place and then the exchange does not operate.
The officials from TLC realized that in such a case it can happen that besides the fact that the place with the failure is unreachable, this can also cause that some other places cannot connect to each other.
In such a case we will say the place (where the failure occured) is critical. Now the officials are trying to write a program for finding the number of all such critical places. Help them.

Input
The input file consists of several blocks of lines. Each block describes one network. In the first line of each block there is the number of places N < 100. Each of the next at most N lines contains the number of a place followed by the numbers of some places to which there is a direct line from this place.
These at most N lines completely describe the network, i.e., each direct connection of two places in
the network is contained at least in one row. All numbers in one line are separated by one space. Each block ends with a line containing just ‘0’. The last block has only one line with N = 0.

Output
The output contains for each block except the last in the input file one line containing the number of
critical places.

Sample Input
5
5 1 2 3 4
0
6
2 1 3
5 4 6 2
0
0
Sample Output
1
2

題目大意:求所給無向圖中,有多少個割點?

無向圖
割點的定義:無向連通圖的割點(關鍵點)是指刪除該結點及與其相連的邊之後,無向圖不再連通。上圖中割頂有:1,2,5,9.

割點的性質:

    1、考慮根頂點Root。
    如果頂點x和y同是Root的兒子,那麼x無法通過非Root的頂點與y相連,所以當根Root有數量>1的兒子時,根是圖的割頂;
    2、考慮非根頂點i,設i的某個兒子是j
    ①和j相連的白色結點都將成爲j的子孫;
    ②和j相連的灰色結點都是j的祖先,由j指向i祖先的邊稱爲後向邊;
    ③黑色結點不可能與j相連
    如果jj的子孫都不存在指向i祖先的後向邊,那麼刪除頂點i後,頂點ji的祖先或者兄弟將無法連通。因此,當且僅當i的某個兒子及兒子的子孫均沒有指向i祖先的後向邊時,i是圖的割頂。

AC代碼:

# include <stdio.h>
# include <string.h>

# define MAXN 10005

struct Edge
{
    int to;
    int next;
}edge[MAXN];

int DFN[MAXN];
int LOW[MAXN];
int head[MAXN], tot;
int Index;
int top;
int cut[MAXN]; //割點

void Init()
{
    tot = 0;
    memset(head, -1, sizeof(head));
    Index = 0;
    memset(DFN, 0, sizeof(DFN));
    memset(LOW, 0, sizeof(LOW));
    memset(cut, 0, sizeof(cut));
}

void addedge(int u, int v)
{
    edge[tot].to = v;
    edge[tot].next = head[u];
    head[u] = tot++;
}

void tarjan(int u, int pre)
{
    int v;
    LOW[u] = DFN[u] = ++ Index;
    int son = 0;
    for (int i = head[u]; i != -1; i = edge[i].next)
    {
        v = edge[i].to;
        if (v == pre)
        {
            continue;
        }
        if (!DFN[v])
        {
            son ++;
            tarjan(v, u);
            if (LOW[u] > LOW[v])
            {
                LOW[u] = LOW[v];
            }
            if (u != pre && LOW[v] >= DFN[u]) //當前結點不是根節點時
            {
                cut[u] = true;
            }
        }
        else if (LOW[u] > DFN[v])
        {
            LOW[u] = DFN[v];
        }
    }
    if (u == pre && son > 1)//當前結點是根節點時
    {
        cut[u] = true;
    }
}

void solve(int n)
{
    int i;
    for (i = 1; i <= n; i++)
    {
        if (!DFN[i])
        {
            tarjan(i, i);
        }
    }
    int ans = 0;
    for (i = 1; i <= n; i++)
    {
        if (cut[i])
        {
            ans ++;
        }
    }
    printf("%d\n", ans);
}

int main(void)
{
    int n;
    while (scanf("%d", &n) && n)
    {
        int a, b;
        char ch;
        Init();
        while (scanf("%d", &a) && a)
        {
            while (scanf("%d%c", &b, &ch))
            {
                addedge(a, b);
                addedge(b, a);
                if ('\n' == ch)
                {
                    break;
                }
            }
        }
        solve(n);
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章