poj1470 Closest Common Ancestors

来源:互联网 发布:win7无法启动网络共享 编辑:程序博客网 时间:2024/06/05 02:41
题意给出一颗树, 后给出m 组(u,v)查询;找到每组两个节点的最近公共祖先, 后按祖先数从小到大输出,最近公共祖先 和以其为祖先的数量
#include <iostream>#include <cstdio>#include <cstring>#include <vector>using namespace std;const int M = 1000;vector<int>que[M];int sign[M][M];int Set[M];int num[M];int vist[M];int rd[M];int n, m;void init() {    memset(sign, 0, sizeof(sign));    for(int i = 0; i < M; i++){        //Set[i] = i;        num[i] = 0;        vist[i] = 0;        rd[i] = 0;        que[i].clear();    }}int Find(int x) {    return x == Set[x] ? x : Set[x] = Find(Set[x]);}void LCA(int u) {    int v;    Set[u] = u;    for(int i = 0; i < (int)que[u].size(); i++){        v = que[u][i];        LCA(v);        Set[v] = u;    }    vist[u] = 1;    for(int i = 1; i <= n; i++){        if(vist[i] && sign[u][i]){            num[Find(i)] += sign[u][i];        }    }}int main(){    int a, b, c;    while(scanf("%d", &n) != EOF) {         init();        for(int i = 0; i < n; i++){            scanf("%d:(%d)", &a, &b);            for(int j = 0; j < b; j++){                scanf("%d", &c);                que[a].push_back(c);                rd[c]++;            }        }        scanf("%d", &m);        for(int i = 0; i < m; i++){           scanf(" (%d%d)", &a, &b); //正确输入;           //scanf("(%d%d)", &a, &b);   //这种输入将得不到结果;因为双引号后没有空格;            sign[a][b]++;            sign[b][a]++;        }        for(int i = 1; i <= n; i++){            if(rd[i] == 0){                LCA(i);                break;            }        }        for(int i= 1; i <= n; i++){            if(num[i])                printf("%d:%d\n", i, num[i]);        }    }    return 0;}

0 0
原创粉丝点击