• BZOJ 1370 [Baltic2003]Gang团伙:并查集【虚点】


    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1370

    题意:

      在某城市里住着n个人,任何两个认识的人不是朋友就是敌人,而且满足:

        (1)我朋友的朋友是我的朋友。

        (2)我敌人的敌人是我的朋友。

      所有是朋友的人组成一个团伙。

      告诉你关于这n个人的m条信息,即某两个人是朋友,或者某两个人是敌人。

      请你编写一个程序,计算出这个城市最多可能有多少个团伙。

    题解:

      对于一个人a,建两个点a和a+n。

      a+n实际上并不存在,只起到连接的作用,是一个虚点。

      所有与a相连的点都是a的朋友。

      所有与a+n相连的点都是它的敌人。

      如果x和y是朋友,则合并(x,y)。

      如果x和y是敌人,则合并(x,y+n)和(y,x+n)。

      所有在一个集合内的人,都属于同一个团伙。

      统计一下有多少个集合,至少包含一个在[1,n]内的点,即为答案。

    AC Code:

     1 #include <iostream>
     2 #include <stdio.h>
     3 #include <string.h>
     4 #define MAX_N 2005
     5 
     6 using namespace std;
     7 
     8 int n,m;
     9 int ans=0;
    10 int par[MAX_N];
    11 bool vis[MAX_N];
    12 
    13 void init_union_find()
    14 {
    15     for(int i=1;i<=n*2;i++)
    16     {
    17         par[i]=i;
    18     }
    19 }
    20 
    21 int find(int x)
    22 {
    23     return par[x]==x?x:par[x]=find(par[x]);
    24 }
    25 
    26 void unite(int x,int y)
    27 {
    28     int px=find(x);
    29     int py=find(y);
    30     if(px==py) return;
    31     par[px]=py;
    32 }
    33 
    34 bool same(int x,int y)
    35 {
    36     return find(x)==find(y);
    37 }
    38 
    39 void read()
    40 {
    41     cin>>n>>m;
    42     init_union_find();
    43     int x,y;
    44     char p;
    45     for(int i=0;i<m;i++)
    46     {
    47         cin>>p>>x>>y;
    48         if(p=='F') unite(x,y);
    49         else
    50         {
    51             unite(x+n,y);
    52             unite(y+n,x);
    53         }
    54     }
    55 }
    56 
    57 void solve()
    58 {
    59     memset(vis,false,sizeof(vis));
    60     for(int i=1;i<=n;i++)
    61     {
    62         int p=find(i);
    63         if(!vis[p])
    64         {
    65             vis[p]=true;
    66             ans++;
    67         }
    68     }
    69 }
    70 
    71 void print()
    72 {
    73     cout<<ans<<endl;
    74 }
    75 
    76 int main()
    77 {
    78     read();
    79     solve();
    80     print();
    81 }
  • 相关阅读:
    tee命令
    linux优化之SElinux关闭
    (1)使用bash脚本实现批量添加用户
    Django admin管理工具的使用、定制及源码解析
    Mysql常见命令
    树梅派
    19道Python循环遍历,while,for语句测试题,网上看到的题目,自己不看答案全部做了一次,总共3个小时左右
    9*9的矩形,中间有个星号,按不同方向键,星星对应移动
    app在admin中显示成我们想要的中文名
    九九乘法表
  • 原文地址:https://www.cnblogs.com/Leohh/p/7636791.html
Copyright © 2020-2023  润新知