1 条题解

  • 0
    @ 2025-9-10 9:13:07

    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
    上传者