zoukankan      html  css  js  c++  java
  • Ural_1003 Parity(并查集)

      /*发现并查集的应用太巧妙了。。。大体思路:从题中可以看出来如果(i, j)是even
    的话,sum(i-1) 和 sum(j)的奇偶性相同。(i, j)如果是odd的话则其奇偶行不同。定
    义奇偶性为朋友,不同则为敌人。

    这样按照奇偶性分成连个集合。
    same[i] = {x|sum[x]与sum[i]同奇偶}(即i的朋友集)
    diff[i] = {x|sum[x]与sum[i]不同奇偶}(即i的敌人集)

    如果(i, j)是even,则分别合并(same(i-1), same(j))和(dirr[i-1] , diff(j))。如果是
    odd,则因为不是奇就是偶,所以,一个的朋友和另一个的敌人合并(敌人的敌人就是
    朋友,呵呵)

    既合并( same(i-1), diff(j) ), ( diff(i-1), same(j) )。如果出现读入的数据(i, j)的阵营与输入
    的even,odd不相符的话则说明这句是假话。

    ps:数据比较大(10^9),离散化了一下。内存还可以吧,不高不底。^ ^

    My Code:
    */

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>

    using namespace std;

    const int N = 5005;
    const int block = 5005;

    struct eq {
    int x;
    int y;
    char s[10];
    } q[N];

    int p[N*2], tmp[N*2];
    int f[N*2], Rank[N*2];
    int cnt, n;

    void init() {
    for(int i = 0; i <= N+N; i++) {
    f[i] = i; Rank[i] = 0;
    }
    }

    int get_p(int x) {
    int l, r, mid;
    l = 0; r = cnt-1;
    while(l < r) {
    mid = (l + r) >> 1;
    if(p[mid] >= x) r = mid;
    else l = mid + 1;
    }
    return l;
    }

    int find(int x) {
    int k, r, j;
    r = x; k = x;
    while(r != f[r]) r = f[r];

    while(k != r) {
    j = f[k];
    f[k] = r;
    k = j;
    }
    return r;
    }

    void union_set(int x, int y) {
    x = find(x);
    y = find(y);
    if(x == y) return ;
    if(Rank[x] > Rank[y]) f[y] = x;
    else {
    f[x] = y;
    if(Rank[x] == Rank[y]) ++Rank[y];
    }
    }

    int main() {
    //freopen("data.in", "r", stdin);

    int M, i, x, y;
    while(~scanf("%d", &M)) {
    if(M == -1) break;

    scanf("%d", &n);


    for(i = 0; i < n; i++) {
    scanf("%d%d %s", &q[i].x, &q[i].y, q[i].s);
    q[i].x--;
    tmp[i*2] = q[i].x;
    tmp[i*2+1] = q[i].y;
    }
    init();
    sort(tmp, tmp+n+n);
    p[0] = tmp[0]; cnt = 1;

    for(i = 1; i < n+n; i++) {
    if(tmp[i] != tmp[i-1]) p[cnt++] = tmp[i];

    }

    for(i = 0; i < n; i++) {

    x = get_p(q[i].x);
    y = get_p(q[i].y);

    if(q[i].s[0] == 'e') {
    if(find(x) == find(y + block)) break;
    union_set(x, y);
    union_set(x + block, y + block);
    } else {
    if(find(x) == find(y)) break;
    union_set(x, y + block);
    union_set(x + block, y);
    }
    }
    printf("%d\n", i);
    }
    return 0;
    }
  • 相关阅读:
    null in ABAP and nullpointer in Java
    SAP ABAP SM50事务码和Hybris Commerce的线程管理器
    Hybris service layer和SAP CRM WebClient UI架构的横向比较
    SAP ABAP和Linux系统里如何检查网络传输的数据量
    SAP CRM WebClient UI和Hybris的controller是如何被调用的
    SAP CRM和Cloud for Customer订单中的业务伙伴的自动决定机制
    SAP CRM WebClient UI和Hybris CommerceUI tag的渲染逻辑
    SAP BSP和JSP页面里UI元素的ID生成逻辑
    微信jsapi支付
    微信jsapi退款操作
  • 原文地址:https://www.cnblogs.com/vongang/p/2259423.html
Copyright © 2011-2022 走看看