1 条题解
-
0
C++ :
//用0,1,2分别表示3种动物 #include<stdio.h> #include<string.h> #define Max 50010 //rank[i]:记层数; father[i]:记i的根结点; link[i]: 以i的根为0为基准i属于的动物种类为link[i]; int rank[Max]; //i从link[i]变为j种动物: link[i] = (link[i]+step[j][link[i]])%3 int step[3][3] = {{0, 2, 1}, {1, 0, 2}, {2, 1, 0}}; int n, k, d, x, y, wrong; struct PP { int father; int link; }p[Max]; //初始化:每个元素就是一个集合 void set(int n) { for(int i = 1; i <= n; i++) { p[i].father = i; rank[i] = 0; p[i].link = 0; } } //寻找元素所在集合的根,使用路径压缩来优化该函数 PP f(int i) { PP t; if(p[i].father != i) { t = f(p[i].father); p[i].father = t.father; p[i].link = (t.link+p[i].link)%3; } return p[i]; } // 若为真将x和y所在的集合合并 void Union(int a, int b) { if(a != b){ //要合并的 if(rank[a] >= rank[b]){ p[b].father = a; if(rank[a] == rank[b]) rank[a]++; if(d == 2) p[b].link = (p[b].link+step[(p[x].link+1)%3][p[y].link])%3; else if(d == 1) p[b].link = (p[b].link+step[p[x].link][p[y].link])%3; } else if(rank[a] < rank[b]){ p[a].father = b; if(d == 2) p[a].link = (p[a].link+step[(p[y].link+2)%3][p[x].link])%3; else if(d == 1) p[a].link = (p[a].link+step[p[y].link][p[x].link])%3; } } else{ //不需要合并的 if(d == 1 && p[x].link != p[y].link)wrong++; else if(d == 2 && (p[x].link+1)%3 != p[y].link)wrong++; } } int main() { //freopen("eat.in", "r", stdin); //freopen("eat.out", "w", stdout); int i; PP t1, t2; scanf("%d%d", &n, &k); set(n); for(wrong = i = 0; i < k; i++) { scanf("%d%d%d", &d, &x, &y); if(x > n || y > n){ wrong++; continue; } if(x == y) { if(d == 2) wrong++; continue; } t1 = f(x); t2 = f(y); Union(t1.father, t2.father); } printf("%d\n", wrong); return 0; }Pascal :
var i,x,y,k,n,ans:longint; t:integer; dad:array[0..50001] of word; r:array[0..50001] of byte; function find(i:word):word; var temp:longint; begin if dad[i]=i then exit(i); temp:=dad[i]; dad[i]:=find(dad[i]); r[i]:=(r[temp]+r[i]) mod 3; exit(dad[i]); end; procedure union(x,y,h:longint); var a,b:longint; begin a:=find(x); b:=find(y); dad[a]:=b; r[a]:=(r[y]+h-r[x]+3) mod 3; end; begin readln(n,k); for i:=1 to n do dad[i]:=i; for i:=1 to k do begin readln(t,x,y); if (x>n) or (y>n) then begin inc(ans); continue; end; if t=1 then if find(x)=find(y) then begin if r[x]<>r[y] then begin inc(ans); continue; end; end else union(x,y,0); if t=2 then begin if x=y then begin inc(ans); continue; end; if find(x)=find(y) then begin if r[x]<>(r[y]+1) mod 3 then begin inc(ans); continue; end; end else union(x,y,1); end; end; writeln(ans); end.
- 1
信息
- ID
- 4212
- 时间
- 1000ms
- 内存
- 128MiB
- 难度
- (无)
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者