标签:argc 处理 creat 动物 stream ble can ted strong
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 65430 | Accepted: 19283 |
Description
Input
Output
Sample Input
100 7 1 101 1 2 1 2 2 2 3 2 3 3 1 1 3 2 3 1 1 5 5
Sample Output
3
多了一种关系的种类并查集
v[i] 0和根同类 1吃根 2被根吃
可以发现1->0->2->1.....
可以从向量的角度思考,比如x->y +3%3是1的话说明x吃y
v[x]就是x->fa[x]这个向量的值
发现D-1正好描述了X->Y这个向量的关系
路径压缩和合并的时候都画图用向量推一下就可以了
还有一种做法,是对每个动物x建立3个集合:x表示与x同类的动物,x+n表示要x吃的动物,x+2*n表示吃x的动物。
一些理解
并查集就是维护了一些关系
种类并查集是把知道关系的东西合并,通过分配一个值来处理
另一种做法是把同一类合并
// // main.cpp // poj1182 // // Created by Candy on 31/10/2016. // Copyright ? 2016 Candy. All rights reserved. // #include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; const int N=5e4+5; inline int read(){ char c=getchar();int x=0,f=1; while(c<‘0‘||c>‘9‘){if(c==‘-‘)f=-1;c=getchar();} while(c>=‘0‘&&c<=‘9‘){x=x*10+c-‘0‘;c=getchar();} return x*f; } int n,m,c,x,y,ans=0; int fa[N],v[N]; inline int find(int x){ if(x==fa[x]) return x; int root=find(fa[x]); v[x]=(v[x]+v[fa[x]])%3;//x->fa[x] + fa[x]->root return fa[x]=root; } inline int unn(int x,int y,int op){ int f1=find(x),f2=find(y); if(f1==f2){ if((-v[y]+v[x]+3)%3!=op) return 1; }else{ fa[f1]=f2; v[f1]=(op+v[y]-v[x]+3)%3; } return 0; } int main(int argc, const char * argv[]) { n=read();m=read(); for(int i=1;i<=n;i++) fa[i]=i,v[i]=0; for(int i=1;i<=m;i++){ c=read();x=read();y=read(); if(x>n||y>n||(c==2&&x==y)){ans++;continue;} ans+=unn(x,y,c-1); } printf("%d",ans); return 0; }
来自luogu题解,另一种做法 这题显然要用并查集。因为只有3种动物,我的方法是对每个动物x建立3个集合:x表示与x同类的动物,x+n表示要x吃的动物,x+2*n表示吃x的动物。 对于每个读入的描述D X Y,做以下处理: 如果X或Y不再区间[1,n]中,这句是假话。 D为1 如果x+n或x+2*n与y在同一个集合中说明已知x和y不是同一种动物,这句是假话; 否则,分别将x与y,x+n与y+n,x+2*n与y+2*n合并。 D为2 如果x与y在同一个集合中,说明已知x和y是同一种动物,这句是假话; 如果x+2*n与y在同一个集合中,说明已知y吃x,这句是假话; 否则,分别将x与y+2*n,x+n与y,x+2*n与y+n合并。 <hr> 说起来很复杂,实现起来其实很简单,代码见下: #include<iostream> #include<algorithm> using namespace std; int p[150001]; int Find(int x) { return x == p[x] ? x : p[x] = Find(p[x]); } void Init(int n) { for (int i = 1; i <= 3 * n; i++) p[i] = i; } void Union(int x, int y) { int xx = Find(x), yy = Find(y); if (xx != yy) p[xx] = yy; } int main() { int n, k, ans = 0; cin >> n >> k; Init(n); for (int i = 1; i <= k; i++) { int a, x, y; cin >> a >> x >> y; if (x > n || y > n || x < 1 || y < 1) { ans++; continue; } if (a == 1) { if (Find(x + n) == Find(y) || Find(x + 2 * n) == Find(y)) { ans++; continue; } Union(x, y); Union(x + n, y + n); Union(x + 2 * n, y + 2 * n); } else { if (Find(x) == Find(y) || Find(x + 2 * n) == Find(y)) { ans++; continue; } Union(x, y + 2 * n); Union(x + n, y); Union(x + 2 * n, y + n); } } cout << ans; }
标签:argc 处理 creat 动物 stream ble can ted strong
原文地址:http://www.cnblogs.com/candy99/p/6018762.html