题目链接:https://atcoder.jp/contests/abc157/tasks/abc157_d
题目大意
有$N$个人,他们之间有$M$对直接好友关系和$K$对封闭关系。
求每个人有多少个间接好友。
分析
非常明显的并查集,不解释了。
代码如下
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 /*-------------------Define Start-------------------*/ 5 typedef bool BL; // 布尔类型 6 typedef char SB; // 有符号1字节,8位 7 typedef unsigned char UB; // 无符号1字节,8位 8 typedef short SW; // 有符号短整型,16位 9 typedef unsigned short UW; // 无符号短整型,16位 10 typedef long SDW; // 有符号整型,32位 11 typedef unsigned long UDW; // 无符号整型,32位 12 typedef long long SLL; // 有符号长整型,64位 13 typedef unsigned long long ULL; // 无符号长整型,64位 14 typedef char CH; // 单个字符 15 typedef float R32; // 单精度浮点数 16 typedef double R64; // 双精度浮点数 17 18 #define Rep(i, n) for (register SDW i = 0; i < (n); ++i) 19 #define For(i, s, t) for (register SDW i = (s); i <= (t); ++i) 20 #define rFor(i, t, s) for (register SDW i = (t); i >= (s); --i) 21 #define foreach(i, c) for (__typeof(c.begin()) i = c.begin(); i != c.end(); ++i) 22 #define ms0(a) memset(a,0,sizeof(a)) 23 #define msI(a) memset(a,0x7f,sizeof(a)) 24 #define LOWBIT(x) ((x)&(-x)) 25 26 #define MP make_pair 27 #define PB push_back 28 #define ft first 29 #define sd second 30 #define ALL(x) x.begin(),x.end() 31 32 #define pr(x) cout << #x << " = " << x << " " 33 #define prln(x) cout << #x << " = " << x << endl 34 35 const ULL mod = 1e9 + 7; //常用模数(可根据题目需要修改) 36 const ULL inf = 0x7fffffff; //用来表示无限大 37 const ULL infLL = 0x7fffffffffffffffLL; //用来表示无限大 38 /*-------------------Define End-------------------*/ 39 40 // 重载<<操作符,用来打印vector 41 template < typename T > 42 ostream& operator<< (ostream& out, vector< T > vec) { 43 foreach(i, vec) { 44 if(i != vec.begin()) { 45 out << " "; 46 } 47 out << *i; 48 } 49 return out; 50 } 51 52 const UDW maxN = 1e5 + 7; 53 SDW N, M, K; 54 vector< SDW > ans; 55 56 SDW dsu[maxN], sz[maxN]; // DISJOINT_SET_UNION 并查集 57 58 SDW Find(SDW x){ 59 while (x != dsu[x]) x = dsu[x] = dsu[dsu[x]]; 60 return x; 61 } 62 63 void Union(SDW x, SDW y){ 64 if (sz[x] > sz[y]) swap(x, y); 65 dsu[x] = y; 66 sz[y] += sz[x]; 67 } 68 69 void input(){ 70 cin >> N >> M >> K; 71 72 // 并查集初始化 73 Rep(i, N) { 74 dsu[i] = i; 75 sz[i] = 1; 76 } 77 78 ans.assign(N, 0); 79 } 80 81 void solve(){ 82 SDW A, B, C, D; 83 84 Rep(i, M) { 85 cin >> A >> B; 86 SDW x = Find(--A); 87 SDW y = Find(--B); 88 if(x != y) { 89 Union(x, y); 90 } 91 --ans[A]; // 减去直接好友关系数 92 --ans[B]; // 减去直接好友关系数 93 } 94 95 Rep(i, N) { 96 SDW x = Find(i); 97 ans[i] += sz[x] - 1; // 加上间接好友关系数和直接好友关系数 98 } 99 100 Rep(i, K) { 101 cin >> C >> D; 102 SDW x = Find(--C); 103 SDW y = Find(--D); 104 if(x == y) { 105 --ans[C]; // 减去间接坏友关系数 106 --ans[D]; // 减去间接坏友关系数 107 } 108 } 109 } 110 111 void output(){ 112 cout << ans << endl; 113 } 114 115 int main() { 116 input(); 117 solve(); 118 output(); 119 return 0; 120 }