zoukankan      html  css  js  c++  java
  • Lightoj1009 Back to Underworld(带权并查集)

    转载请注明出处: http://www.cnblogs.com/fraud/           ——by fraud

    Back to Underworld
    Time Limit:4000MS     Memory Limit:32768KB     64bit IO Format:%lld & %llu

    Description

    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

    2

    2

    1 2

    2 3

    3

    1 2

    2 3

    4 2

    Sample Output

    Case 1: 2

    Case 2: 3

    问其中两个种族的数目较大的那个值最大可能是多少。

    典型的带权并查集。

    已知u和v不在一个种族,所需处理的手段就是,把u和非v放到一个集合,把v和非u放到一个集合。利用u+MAXN来表示非u,非v也是同理。

    此外,维护好每一个集合中的节点的数目,取非的不要放到算入计数。

    然后枚举每个点,看他们所在的集合,取一个较大值。注意不要重复取

      1 //#####################
      2 //Author:fraud
      3 //Blog: http://www.cnblogs.com/fraud/
      4 //#####################
      5 //#pragma comment(linker, "/STACK:102400000,102400000")
      6 #include <iostream>
      7 #include <sstream>
      8 #include <ios>
      9 #include <iomanip>
     10 #include <functional>
     11 #include <algorithm>
     12 #include <vector>
     13 #include <string>
     14 #include <list>
     15 #include <queue>
     16 #include <deque>
     17 #include <stack>
     18 #include <set>
     19 #include <map>
     20 #include <cstdio>
     21 #include <cstdlib>
     22 #include <cmath>
     23 #include <cstring>
     24 #include <climits>
     25 #include <cctype>
     26 using namespace std;
     27 #define XINF INT_MAX
     28 #define INF 0x3FFFFFFF
     29 #define MP(X,Y) make_pair(X,Y)
     30 #define PB(X) push_back(X)
     31 #define REP(X,N) for(int X=0;X<N;X++)
     32 #define REP2(X,L,R) for(int X=L;X<=R;X++)
     33 #define DEP(X,R,L) for(int X=R;X>=L;X--)
     34 #define CLR(A,X) memset(A,X,sizeof(A))
     35 #define IT iterator
     36 typedef long long ll;
     37 typedef pair<int,int> PII;
     38 typedef vector<PII> VII;
     39 typedef vector<int> VI;
     40 const int MAXN = 20010;
     41 int pa[MAXN*3];
     42 int ra[MAXN*3];
     43 void init(int n){
     44     for(int i=0;i<n;i++){
     45         pa[i] = i;
     46         ra[i] = 0;
     47     }
     48 }
     49 int find(int x){
     50     if(pa[x]!=x)pa[x] = find(pa[x]);
     51     return pa[x];
     52 }
     53 int unite(int x,int y){
     54     x = find(x);
     55     y = find(y);
     56     if(x==y)return 0;
     57     if(ra[x]<ra[y]){
     58         pa[x] = y;
     59     }else{
     60         pa[y] = x;
     61         if(ra[x]==ra[y])ra[x]++;
     62     }
     63     return 1;
     64 }
     65 bool same(int x,int y){
     66     return find(x) == find(y);
     67 }
     68 int used[MAXN*3];
     69 int num[MAXN*3];
     70 int vis[MAXN*3];
     71 int main()
     72 {
     73     ios::sync_with_stdio(false);
     74     int t;
     75     cin>>t;
     76     int cas = 1;
     77     while(t--){
     78         int n;
     79         cin>>n;
     80         init(MAXN*2);
     81         int u,v;
     82         memset(used,0,sizeof(used));
     83         for(int i=0;i<n;i++){
     84             cin>>u>>v;
     85             u--;v--;
     86             used[u] = used[v] = 1;
     87             unite(u,v+MAXN);
     88             unite(v,u+MAXN); 
     89         }
     90         memset(num,0,sizeof(num));
     91         for(int i=0;i<MAXN;i++){
     92             if(used[i]){
     93                 int fa = find(i);
     94                 num[fa]++;
     95             }
     96         }
     97         int x,y;
     98         memset(vis,0,sizeof(vis));
     99         int ans = 0;
    100         for(int i=0;i<MAXN;i++){
    101             if(used[i]){
    102                 x = find(i);
    103                 y = find(i+MAXN);
    104                 if(vis[x]||vis[y])continue;
    105                 ans += max(num[x],num[y]);
    106                 vis[x] = vis[y] = 1;
    107             }
    108         }
    109         cout<<"Case "<<cas++<<": "<<ans<<endl;
    110     }
    111             
    112     return 0;
    113 }
  • 相关阅读:
    在Mybatis中使用连表查询的一次实际应用
    Mybatis使用generatedKey在插入数据时返回自增id始终为1,自增id实际返回到原对象当中的问题排查
    一次org.springframework.jdbc.BadSqlGrammarException ### Error querying database Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException问题排查过程
    商品的spu、sku及其之间的关系
    Java transient关键字的理解
    关于Serializable的一个形象的例子
    一个很大的文件,存放了10G个整数的乱序数列,如何用程序找出中位数。
    Logger.error方法之打印错误异常的详细堆栈信息
    什么是Http无状态?Session、Cookie、Token三者之间的区别
    接口API中的敏感数据基于AES进行安全加密后返回
  • 原文地址:https://www.cnblogs.com/fraud/p/4665866.html
Copyright © 2011-2022 走看看