并查集专题
B
模板题,我他妈的wa了一万发,后来发现有东西变化了。。。
AC code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
| #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; int n, m; const int maxn = 3e4+10; int fa[maxn]; int num[maxn]; int find_fa(int x){ int a = x; while(x!=fa[x]){ x = fa[x]; } while(a!=fa[a]){ int z = a; a = fa[a]; fa[z] = x; } return x; } void uni(int u, int v){ int fau = find_fa(u); int fav = find_fa(v); if(fau!=fav)fa[fau] = fav; } void init(){ for(int i=0; i<maxn; i++) fa[i] = i; } int main(){ while(scanf("%d%d", &n, &m)!=EOF&&(n||m)){ int k; init(); for(int i=0; i<m; i++){ scanf("%d", &k); for(int j=0; j<k; j++){ scanf("%d", &num[j]); } for(int j=1; j<k; j++){ uni(num[0], num[j]); } } int ans = 0; for(int i=0; i<n; i++){ find_fa(i); } int father = fa[0]; for(int i=0; i<n; i++){ if(fa[i] == father) ans++; } printf("%d\n", ans); } }
|
E食物链
有两个教训:
- 只有一组数据的时候,不要用eof来判断
- 老老实实用scanf来读取数据,关同步照样会超时的。
题解
划分为三个集合,若有关系,那么就在集合之间连一条边。
AC代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
| #include <iostream> #include <cstdio> #include <cstring> #include<queue> #include <algorithm> #include <vector> using namespace std; const int maxn = 5e4+10; int fa[maxn*3+10]; int find_fa(int x){ int a = x; while(x!=fa[x]){ x = fa[x]; } while(a!=fa[a]){ int z = a; a = fa[a]; fa[z] = x; } return x; } void uni(int u, int v){ int fau = find_fa(u); int fav = find_fa(v); fa[fau] = fav; } void init(){ for(int i=0; i<maxn*3; i++) fa[i] = i; } bool same(int u, int v){ int fau = find_fa(u); int fav = find_fa(v); return fau==fav?true:false; } int n, k; int main(){ ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); cin>>n>>k; { init(); int ans = 0; int op, a, b; for(int i=0; i<k; i++){ cin>>op>>a>>b; if(a>n||b>n){ ans++; continue; } else if(op == 2&&a == b){ ans++; continue; } if(op == 1){ if(same(a, b+n)||same(a, b+2*n)){ ans++; continue; } uni(a, b); uni(a+n, b+n); uni(a+2*n, b+2*n); } else{ if(same(a, b)||same(a, b+2*n)){ ans++; continue; } uni(a, b+n); uni(a+n, b+2*n); uni(a+2*n, b); } } cout<<ans<<endl; } return 0; }
|
未解决的问题