zoukankan      html  css  js  c++  java
  • E. Anton and Tree 数组开大点

    http://codeforces.com/contest/734/problem/E

    看了题解,缩点 + 树的直径。

    然而一直wa14.

    注意到,

    缩点后重建图,在5的时候,5和6建了一条边,然后6的时候,又和5建一次边。这个时候就要大数组了。

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #define IOS ios::sync_with_stdio(false)
    using namespace std;
    #define inf (0x3f3f3f3f)
    typedef long long int LL;
    
    #include <iostream>
    #include <sstream>
    #include <vector>
    #include <set>
    #include <map>
    #include <queue>
    #include <string>
    const int maxn = 2 * 200000 + 20;
    int first[maxn];
    int first_sec[maxn];
    int num, num_sec;
    struct node {
        int u, v, w;
        int tonext;
    }e[maxn * 2], e_sec[maxn * 2];
    int col[maxn];
    void add(int u, int v) {
        ++num;
        e[num].u = u;
        e[num].v = v;
        e[num].tonext = first[u];
        first[u] = num;
    }
    void add_sec(int u, int v) {
        ++num_sec;
        e_sec[num_sec].u = u;
        e_sec[num_sec].v = v;
        e_sec[num_sec].tonext = first_sec[u];
        first_sec[u] = num_sec;
    }
    bool vis[maxn];
    int fa[maxn];
    int find(int u) {
        if (u == fa[u]) return u;
        else return fa[u] = find(fa[u]);
    }
    void merge(int u, int v) {
        u = find(u);
        v = find(v);
        if (u != v) {
            fa[v] = u;
        }
    }
    void dfs(int cur) {
        for (int i = first[cur]; i; i = e[i].tonext) {
            int v = e[i].v;
            if (vis[v]) continue;
            vis[v] = true;
            if (col[cur] == col[v]) {
                merge(cur, v);
            }
            dfs(v);
        }
    }
    void dfs2(int cur) {
        printf("cur %d : %d
    ", cur, col[cur]);
        for (int i = first_sec[cur]; i; i = e_sec[i].tonext) {
            int v = e_sec[i].v;
            if (vis[v]) continue;
            vis[v] = true;
            dfs2(v);
        }
    }
    struct NODE {
        int cur, cnt;
        NODE(int aa, int bb) : cur(aa), cnt(bb) {}
    };
    int bfs(int begin) {
        memset(vis, 0, sizeof vis);
        queue<struct NODE>que;
        while(!que.empty()) que.pop();
        que.push(NODE(begin, 0));
        vis[begin] = true;
        int mx = -inf;
        int to = begin;
        while (!que.empty()) {
            struct NODE t = que.front();
            que.pop();
            for (int i = first_sec[t.cur]; i; i = e_sec[i].tonext) {
                int v = e_sec[i].v;
                if (vis[v]) continue;
                que.push(NODE(v, t.cnt + 1));
                vis[v] = true;
                if (mx < t.cnt + 1) {
                    mx = t.cnt + 1;
                    to = v;
                }
            }
        }
        if (to == begin) return 0;
    //    cout << to << " " << mx << endl;
        que.push(NODE(to, 0));
        memset(vis, 0, sizeof vis);
        vis[to] = true;
        mx = -inf;
        to = 0;
        while (!que.empty()) {
            struct NODE t = que.front();
            que.pop();
            for (int i = first_sec[t.cur]; i; i = e_sec[i].tonext) {
                int v = e_sec[i].v;
                if (vis[v]) continue;
                que.push(NODE(v, t.cnt + 1));
                if (mx < t.cnt + 1) {
                    mx = t.cnt + 1;
                    to = v;
                }
                vis[v] = true;
            }
        }
    //    cout << mx << " " << to << endl;
        return mx;
    }
    void work() {
        int n;
        scanf("%d", &n);
        for (int i = 1; i <= n; ++i) fa[i] = i;
        for (int i = 1; i <= n; ++i) scanf("%d", &col[i]);
        for (int i = 1; i <= n - 1; ++i) {
            int u, v;
            scanf("%d%d", &u, &v);
            add(u, v);
            add(v, u);
            if (num > 200000 * 2) while(1);
        }
        vis[1] = true;
        dfs(1);
    //    for (int i = 1; i <= n; ++i) {
    //        printf("%d
    ", find(i));
    //    }
        for (int i = 1; i <= n; ++i) {
            for (int j = first[i]; j; j = e[j].tonext) {
                int v = e[j].v;
                if (find(i) == find(v)) continue;
    //            printf("%d %d
    ", find(i), find(v));
    //            printf("fff");
                add_sec(find(i), find(v));
                add_sec(find(v), find(i));
            }
        }
    //    memset(vis, 0, sizeof vis);
    //    vis[1] = 1;
    //    dfs2(1);
        int ans = bfs(find(1));
        cout << (ans + 1) / 2 << endl;
    }
    
    int main() {
    #ifdef local
        freopen("data.txt","r",stdin);
    #endif
        work();
        return 0;
    }
    View Code

    为什么直径 /  2是答案?因为可以在直径中间的那个点,一直变一直变。

  • 相关阅读:
    (转)Web自动化测试中的接口测试
    Redis在.net中的应用学习
    Redis学习第八课:Redis高级实用特性(一)
    Redis学习第七课:键值命令和服务器命令
    Redis学习第六课:Redis ZSet类型及操作
    先验概率 vs 后验概率
    cout格式化输出
    python练习linux下创建路径
    把“苹果中国首发”视为扬眉吐气是自卑的表现
    字符串处理算法(三)按指定位置交换字符串两部分的位置
  • 原文地址:https://www.cnblogs.com/liuweimingcprogram/p/6093446.html
Copyright © 2011-2022 走看看