首页 > 其他分享 >TZOJ 5784: 团伙 并查集

TZOJ 5784: 团伙 并查集

时间:2023-03-15 13:59:13浏览次数:45  
标签:并集 int 查集 团伙 5784 朋友 TZOJ 敌人 find

描述

 

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

1、我朋友的朋友是我的朋友;

2、我敌人的敌人是我的朋友;

所有是朋友的人组成一个团伙。告诉你关于这n个人的m条信息,即某两个人是朋友,或者某两个人是敌人,请你编写一个程序,计算出这个城市最多可能有多少个团伙?

 

 

输入

 

第1行为n和m,1<n<1000,1≤m≤100 000;

以下m行,每行为p x y,p的值为0或1,p为0时,表示x和y是朋友,p为1时,表示x和y是敌人。

 

 

输出

 

一个整数,表示这n个人最多可能有几个团伙。

 

样例输入

 

6 4
1 1 4
0 3 5
0 4 6
1 1 2

样例输出

3

思路:对于朋友,直接并集,对于敌人,那么需要将所有敌人用二维数组存储起来,a[x][0]的数值代表x的敌人数量,然后让敌人并集

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N = 1005;
 4 int a[N][N],f[N];
 5 int p,x,y;
 6 int find(int x)
 7 {
 8     if(f[x]!=x)f[x] = find(f[x]);
 9     return f[x];
10 }
11 void merger(int x,int y)
12 {
13     f[y] = x;
14 }
15 int main()
16 {
17     int n,m;
18     cin>>n>>m;
19     for(int i=1;i<=n;i++)f[i] = i;
20     for(int i=1;i<=m;i++)
21     {
22         cin>>p>>x>>y;
23         if(p==0)
24         {
25             if(find(x)!=find(y))
26                 merger(x,y);
27         }
28         else //a[x][0]代表x有a[x][0]个敌人,遍历敌人数量,然后将敌人和y并集 
29         {
30             for(int j=1;j<=a[x][0];j++) //y和x的敌人并集 
31             {
32                 int fa = find(y);
33                 int fb = find(a[x][j]);
34                 if(fa!=fb)merger(fa,fb);
35             }
36             for(int j=1;j<=a[y][0];j++) //x和y的敌人并集 
37             {
38                 int fa = find(x);
39                 int fb = find(a[y][j]);
40                 if(fa!=fb)merger(fa,fb);
41             }
42             a[x][++a[x][0]] = y; //将y加入x的敌人 
43             a[y][++a[y][0]] = x; //将x加入y的敌人 
44             
45         }
46     }
47     int ans = 0;
48     for(int i=1;i<=n;i++)
49         if(f[i]==i)ans++;
50     cout<<ans;
51      return 0;
52 }

 

标签:并集,int,查集,团伙,5784,朋友,TZOJ,敌人,find
From: https://www.cnblogs.com/jyssh/p/17218212.html

相关文章

  • ABC 293 ABCD(并查集)
    A-SwapOddandEven#include<bits/stdc++.h>usingnamespacestd;typedeflonglongLL;typedefpair<LL,LL>PII;constLLMAXN=1e18,MINN=-1e18;constLLN=1e6......
  • TZOJ 3196: 看病要排队 优先队列
    描述看病要排队这个是地球人都知道的常识。不过经过细心的0068的观察,他发现了医院里排队还是有讲究的。0068所去的医院有三个医生(汗,这么少)同时看病。而看病的人病情有轻......
  • 并查集一
    并查集一当我们需要快速判断两个元素是否归属于同一个集合或者将两个集合合并时,就会使用并查集 #include<iostream>usingnamespacestd;constintN=1e5+1......
  • [蓝桥杯 2019 省 A] 修改数组 ———并查集练习(大学复健)
    本题拿到第一反应桶排序思想似乎可以水过,但是很明显出问题了。#include<bits/stdc++.h>usingnamespacestd;intN;inlineintkd(){ intx=0,f=1;charch=getchar......
  • 蓝桥杯 & 青蛙过河(最快贪心) (不用并查集)
      点击查看代码#include<bits/stdc++.h>usingnamespacestd;typedeflonglongll;constintN=1000000+7;lla[N];llb[N];llc[N];lln,x;boolcheck(ll......
  • 并查集模板
    #include<bits/stdc++.h>usingnamespacestd;intfa[10005];intm,n;intfind(intx){ if(fa[x]!=x){ fa[x]=find(fa[x]); } returnfa[x];}booljudge(intx,......
  • TZOJ 4767: 二叉树遍历
    描述  给定一颗二叉树,要求输出对二叉树进行先序和后序遍历所得到的序列。本题假设二叉树的结点数不超过1000。  输入  输入数据分为多组,第一行是测试数......
  • 【并查集】LeetCode 990. 等式方程的可满足性
    题目链接990.等式方程的可满足性思路并查集模板题,模板可以参考常用算法模板。将字母视为结点,==表示有路径,!=表示无路径。遍历x==y,建立图前驱关系遍历x!=y,......
  • history 题解(并查集)
    考虑使用边带权并查集维护点之间的连通性,边权为这条边建立的时间,查询时如果查询时间小于边权则不能通行(巧妙地处理了时间的性质)。由于时间这种东西性质特殊无法路径压缩,所......
  • CF-25D - Roads not only in Berland(并查集或者搜索)
    D-RoadsnotonlyinBerlandCrawlinginprocess...CrawlingfailedTimeLimit:2000MSMemoryLimit:262144KB64bitIOFormat:%I64d&%I64u​​Submit​​......