poj 1470 lca-targan离线算法

来源:互联网 发布:小熊相机软件 编辑:程序博客网 时间:2024/05/17 15:39

题意:

给一棵树n个节点,然后一些k个询问u,v。

最后输出的是每个询问中被询问的u,v的最近公共祖先和被访问的次数。


解析:

用targan离线处理,每次遇到访问则cnt++。


代码:

#include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#include <vector>#include <queue>#include <map>#include <set>#include <climits>#include <cassert>#define Min(a,b) ((a)<(b)?(a):(b))#define Max(a,b) ((a)>(b)?(a):(b))#define LL long long#define lson lo, mi, rt << 1#define rson mi + 1, hi, rt << 1 | 1using namespace std;const int maxn = 1000 + 10;const int maxq = 500000 + 10;const int inf = 0x3f3f3f3f;const double eps = 1e-8;const double pi = acos(-1.0);const double ee = exp(1.0);int cnt[maxn];int n;vector<int> node[maxn], query[maxq];int inDegree[maxn];int ancestor[maxn];bool vis[maxn];int fa[maxn];int Rank[maxn];void Init(int n){    memset(cnt, 0, sizeof(cnt));    for (int i = 1; i <= n; i++)    {        fa[i] = i;        Rank[i] = 0;        node[i].clear();        query[i].clear();    }    memset(vis, false, sizeof(vis));    memset(inDegree, 0, sizeof(inDegree));    memset(ancestor, 0, sizeof(ancestor));}int Find(int x){    if (fa[x] != x)        fa[x] = Find(fa[x]);    return fa[x];}void Union(int u, int v){    int fau = Find(u);    int fav = Find(v);    if (fau == fav)        return;    if (Rank[fau] < Rank[fav])    {        fa[fau] = fav;    }    else    {        fa[fav] = fau;        if (Rank[fau] == Rank[fav])            Rank[fau]++;    }}void lca(int rt){    int sz = node[rt].size();    //自成集合    ancestor[rt] = rt;    for (int i = 0; i < sz; i++)    {        lca(node[rt][i]);           //递归子树        Union(rt, node[rt][i]);     //合并子树与根        int id = Find(node[rt][i]);        ancestor[id] = rt;          //子树祖先也指向根    }    vis[rt] = true;    sz = query[rt].size();    for (int i = 0; i < sz; i++)    {        if (vis[query[rt][i]])        {            int id = Find(query[rt][i]);            cnt[ancestor[id]]++;//            printf("%d\n", ancestor[id]);        }    }    return;}int main(){#ifdef LOCAL    freopen("in.txt", "r", stdin);#endif // LOCAL    int n, q;    while (~scanf("%d", &n))    {        Init(n);        for (int i = 1; i <= n; i++)        {            int u, k;            scanf("%d:(%d)", &u, &k);            while (k--)            {                int v;                scanf("%d", &v);                inDegree[v]++;                node[u].push_back(v);////                node[v].push_back(u);            }        }        scanf("%d", &q);        for (int i = 0; i < q; i++)        {            int u, v;            char c;            cin >> c;            scanf("%d %d)", &u, &v);            query[u].push_back(v);            query[v].push_back(u);        }        int rt;        for (int i = 1; i <= n; i++)        {            if (!inDegree[i])            {                rt = i;                break;            }        }        lca(rt);        for (int i = 1; i <= n; i++)        {            if (cnt[i])            {                printf("%d:%d\n", i, cnt[i]);            }        }    }    return 0;}


0 0
原创粉丝点击