3 条题解
-
0
提供一个扩展并查集的做法,洛谷有原题。
以 来表示与 相关的另一个值,从而以 的空间来维护一个并查集。
那么如何维护这个并查集呢?只要按照题目的意思就行了。比如 是朋友,只需要合并 。而如果是敌人,那么只需要合并 和 。
而且敌人的敌人就是朋友,所以也可以套回来。
int find(int x) { return fa[x]==x ? x : fa[x]=find(fa[x]) ; } // 路径压缩 void link(int x, int y) // 合并 x,y { int fx = find(x), fy = find(y); fa[fx] = fy; } void solve() { cin>>n>>m; F(i,1,2*n) fa[i] = i; // 关键初始化 F(i,1,m){ char opt; int p,q; cin>>opt>>p>>q; if (opt=='0') { link(p, q); // 不需要合并敌人的原因是,朋友的敌人不一定是自己的敌人。 } if (opt=='1') { link(p+n, q); link(q+n, p); } } int ans = 0; F(i,1,n) ans += fa[i]==i ; // 这样之后会形成一个森林(每棵树都是并查集建出来的树),只需要统计树根数量。 cout<<ans<<endl; }
-
0
关于题面的一些个人解释:
- 我的敌人的敌人是我的朋友,意思是我的朋友的敌人的敌人不一定是我的敌人,只是字面意思,并非阵营大战。
- 题面里的每个认识的人不是朋友就是敌人这句话,指的是两个【认识的人】!换言之,这座城市里还能有不认识的人(费孝通点了个赞)
因为如果不是那样子的话,没有给定亲友关系的节点,如果在遇到一个【有敌人】的节点,就无法视为一个独立的团队了。而输出和楼下题解并不包含这个情况。
举个例子,若城市中有3个人,给定一组关系,A和B是敌人,那么整个城市中最多只有2个团伙。
因为如果C与A是朋友,那么只有2个团伙。而且如果C与A是敌人,那么C与B将会是朋友,仍然只有2个团伙。
- 另外,题面或许应该保证不会出现某个团伙中,A与C是朋友,B与C是朋友,但A与C是敌人的情况。但是我不知道。
如果下次遇到熟人社会的话,只需要在统计答案的时候查一下存不存在【有敌人】的节点,如果有的话孤立那些自闭症的节点就好了。如果不存在,那么只需要制造一个全对立的节点,让他自成一派,再孤立其他自闭症就好。
-
0
就是多了一步合并敌人的敌人,别的基本就是板子 建议训练: tzhsojor洛谷连接(这两是一道题
#include <bits/stdc++.h> #define int long long int using namespace std; const int N = 2e5 + 7; int n,m; int fa[N << 1],e[N]; inline int read(){ int x = 0,f = 1; char c = getchar(); for(;!isdigit(c);c = getchar()) if(c == '-')f = -1; for(;isdigit(c);c = getchar()) x = (x << 1) + (x << 3) + c - '0'; return x * f; } int get(int x){ if(fa[x] == x)return x; return fa[x] = get(fa[x]); } void merge(int x,int y){ x = get(x); y = get(y); fa[x] = y; } void print(int x,int y){ if(get(x) == get(y)) printf("Y\n"); else printf("N\n"); } signed main(){ n = read();m = read(); for(int i = 1;i <= n;i ++){ fa[i] = i; fa[i + n] = i + n; } for(int i = 1;i <= m;i ++){ int p = read(),x = read(),y = read(); if(!p) merge(x,y); else{ if(!e[x]) e[x] = y; else{ merge(e[x],y); } if(!e[y]) e[y] = x; else{ merge(e[y],x); } } } int tot = 0; for(int i = 1;i <= n;i ++) if(fa[i] == i) tot++; printf("%lld",tot); return 0; }
- 1
信息
- ID
- 395
- 时间
- 1000ms
- 内存
- 128MiB
- 难度
- 10
- 标签
- 递交数
- 6
- 已通过
- 4
- 上传者