• Back to Underworld(lightoj 1009)


    1009 - Back to Underworld
    Time Limit: 4 second(s) Memory Limit: 32 MB

    The Vampires and Lykans are fighting each other to death. The war has become so fierce that, none knows who will win. The humans want to know who will survive finally. But humans are afraid of going to the battlefield.

    So, they made a plan. They collected the information from the newspapers of Vampires and Lykans. They found the information about all the dual fights. Dual fight means a fight between a Lykan and a Vampire. They know the name of the dual fighters, but don't know which one of them is a Vampire or a Lykan.

    So, the humans listed all the rivals. They want to find the maximum possible number of Vampires or Lykans.

    Input

    Input starts with an integer T (≤ 10), denoting the number of test cases.

    Each case contains an integer n (1 ≤ n ≤ 105), denoting the number of dual fights. Each of the next n lines will contain two different integers u v (1 ≤ u, v ≤ 20000) denoting there was a fight between u and v. No rival will be reported more than once.

    Output

    For each case, print the case number and the maximum possible members of any race.

    Sample Input

    Output for Sample Input

    2

    2

    1 2

    2 3

    3

    1 2

    2 3

    4 2

    Case 1: 2

    Case 2: 3

    Note

    Dataset is huge, use faster I/O methods.


    PROBLEM SETTER: JANE ALAM JAN

    思路:并查集;

    我们要把上面的点分成两个阵营,p-q表示p,q这两个点是对立的是不同的阵营,那么我们将每一个点分别构造两个不同的阵营,假如是点P;

    那么(p,p+cnt)就为两个不同的阵营的表示法,P-q;也就是p和q+cnt是一个阵营,q和p+cnt是一个阵营,因为p和p+cnt对立,同理。

    那么我们就用并差集来合并,然后最后我们可以得到多个集合,并且,其中的每个集合,在这些集合中我们可以找到他的对立集合,所以我们贪心选取,两个集合中最大的那个,加入sum。

    (注:每个两个点最多有3种关系,1,同一阵营,2不同阵营,3没有关系)

     1 #include<stdio.h>
     2 #include<algorithm>
     3 #include<iostream>
     4 #include<string.h>
     5 #include<stdlib.h>
     6 #include<queue>
     7 #include<map>
     8 using namespace std;
     9 int du[20005*3];
    10 int str[3*20005];
    11 int flag[3*20005];
    12 typedef struct pp
    13 {
    14     int x;
    15     int y;
    16 }ss;ss aa[100005];
    17 map<int,int>my;
    18 int main(void)
    19 {
    20     int n,i,j,k,p,q;
    21     int s;
    22     scanf("%d",&k);
    23     for(s=1;s<=k;s++)
    24     {   my.clear();
    25         scanf("%d",&n);memset(flag,0,sizeof(flag));
    26         for(i=0;i<3*20005;i++)
    27             {str[i]=i;du[i]=1;}
    28             int cnt=1;
    29        for(i=0;i<n;i++)
    30        {
    31            scanf("%d %d",&aa[i].x,&aa[i].y);
    32            if(my[aa[i].x]==0)
    33             my[aa[i].x]=cnt++;
    34            aa[i].x=my[aa[i].x];
    35            if(my[aa[i].y]==0)
    36            my[aa[i].y]=cnt++;
    37            aa[i].y=my[aa[i].y];
    38        }
    39        for(i=cnt;i<3*20005;i++)
    40        du[i]=0;
    41        for(i=0;i<n;i++)
    42        {
    43            int x=aa[i].x;
    44            int y=aa[i].y;
    45            int xx=x+cnt-1;
    46            int yy=y+cnt-1;
    47            int c,c1,c2,c3;
    48            for(c=x;str[c]!=c;)
    49             c=str[c];
    50            for(c1=y;c1!=str[c1];)
    51             c1=str[c1];
    52            for(c2=xx;str[c2]!=c2;)
    53             c2=str[c2];
    54            for(c3=yy;c3!=str[c3];)
    55             c3=str[c3];
    56            if(c!=c3)
    57            {
    58                if(du[c]>=du[c3])
    59                {
    60                    du[c]+=du[c3];
    61                    str[c3]=c;
    62                }
    63                else {du[c3]+=du[c];str[c]=c3;}
    64            }
    65            if(c1!=c2)
    66            {
    67                if(du[c2]>=du[c1])
    68                {
    69                    du[c2]+=du[c1];
    70                    str[c1]=c2;
    71                }
    72                else
    73                {
    74                    du[c1]+=du[c2];
    75                    str[c2]=c1;
    76                }
    77            }
    78        }int sum=0;
    79        for(i=1;i<cnt;i++)
    80        {
    81            int c,d;
    82            for(c=i;c!=str[c];)
    83             {c=str[c];}
    84            for(d=i+cnt-1;d!=str[d];)
    85            {d=str[d];}
    86            if(!flag[c])
    87            {
    88                sum+=max(du[c],du[d]);
    89                flag[c]=1;flag[d]=1;
    90            }
    91        }
    92        printf("Case %d: %d
    ",s,sum);
    93     }return 0;
    94 }
    油!油!you@
  • 相关阅读:
    coffee.js
    domOperation.js
    ImmediateFunc.js
    callback.js
    array.js
    asynchronous.js
    addEventListener.js
    meta的日常设置
    11.11 双十一 前端教你一键领取天猫千张优惠券 (领前先想想有没有钱花这些优惠券)
    前端的最后是逻辑和数学
  • 原文地址:https://www.cnblogs.com/zzuli2sjy/p/5310723.html
Copyright © 2020-2023  润新知