Sicily 1225. 电子眼

1225. 电子眼

Constraints

Time Limit: 1 secs, Memory Limit: 32 MB

Description

Sicily市是一个环境优美,气候宜人的小城市。因为城市的交通并不繁忙,市内的道路网很稀疏。准确来说,Sicily市有N条马路和N个路口,每条马路连接2个路口,每两个路口之间最多只有一条马路。作为一个交通网络,显然每两个路口之间都是可达的。为了更好的管理Sicily市的交通,市长决定在一些路口加装电子眼,用来随时监视路面情况。这些装在路口的电子眼能够监视所有连接到这个路口的马路。现在市长想知道最少需要在多少个路口安装电子眼才能监视所有的马路。市长已经把所有的路口都编上了1..n的号码。

给你Sicily市的地图,你能帮个忙吗?

Input

输入文件的第一行包括一个数字N(1<=N<=100000),表示Sicily市的路口数(马路数)。以下N行,第i+1行的第一个数字Ki表示有Ki条马路与路口i相连,后面紧接着Ki个数字,表示与路口i直接连接的路口。

Output

对于每组测试数据,输出一个数字ans,需要安装电子眼的最少的路口数。

Sample Input

3
2 2 3
2 1 3
2 1 2

Sample Output

2

Problem Source

ZSUACM Team Member

// Problem#: 1225
// Submission#: 3587790
// The source code is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
// URI: http://creativecommons.org/licenses/by-nc-sa/3.0/
// All Copyright reserved by Informatic Lab of Sun Yat-sen University
#include 
#include 
#include 
using namespace std;

const int maxn = 1000010;

int map[maxn * 2];
int Index[maxn + 1];
int k[maxn + 1];
int stack[maxn];
int ptr[maxn];
int a[maxn], b[maxn];
char flag[maxn + 1];
int n;
int p1, p2;

int dfs(int v) {
    int i, j, p;
    memset(flag, 0, sizeof(flag));
    stack[0] = v;
    ptr[0] = 0;
    flag[v] = 1;
    for (p = 0; p >= 0;) {
        i = stack[p];
        if (ptr[p] < k[i]) {
            j = map[Index[i] + ptr[p]];
            ptr[p]++;
            if (p == 0 || j != stack[p - 1]) {
                if (flag[j]) {p1 = i; p2 = j; return 1;}
                else {
                    p++;
                    stack[p] = j;
                    ptr[p] = 0;
                    flag[j] = 1;
                }
            }
        } else p--;
    }
    return 0;
}

int work(int v) {
    int i, j, p;
    stack[0] = v;
    ptr[0] = 0;
    a[0] = 1;
    b[0] = 1;
    for (p = 0; p >= 0;) {
        i = stack[p];
        if (ptr[p] < k[i]) {
            j = map[Index[i] + ptr[p]];
            ptr[p]++;
            if ((i != p1 || j != p2) && (i != p2 || j != p1) && (p == 0 || j != stack[p - 1])) {
                p++;
                stack[p] = j;
                ptr[p] = 0;
                a[p] = 1;
                b[p] = 0;
            }
        } else {
            if (p > 0) {
                a[p - 1] += min(a[p], b[p]);
                b[p - 1] += a[p];
            }
            p--;
        }
    }
    return a[0];
}

int main() {
    int i, j, t, c1, c2;
    scanf("%d", &n);
    for (i = 1, t = 0; i <= n; i++) {
        Index[i] = t;
        scanf("%d", &k[i]);
        for (j = 0; j < k[i]; j++) scanf("%d", &map[t++]);
    }
    dfs(1);
    c1 = work(p1);
    c2 = work(p2);
    printf("%d\n", min(c1, c2));
    return 0;
}                                 


你可能感兴趣的:(sicily)