問題解決のアイデア
悲しいかな、最初は間違った質問の意味を理解し、裸の質問を入力して確認しました。。。私は野菜すぎますああああああああ
巨人は、この質問には2つの方法があるようだと言いました。
アルゴリズム1:ドメインを展開し、セットを見つけます
ユニオン検索セットの新しい拡張機能である拡張ドメインユニオン検索セットを導入します。
このアプローチでは、グラフ理論の古典的な考え方を使用します。分割ポイント、つまり、グラフ内の各ノードが複数の情報を表す必要がある場合、各ノードは複数のポイントに分割され、分割された各ポイントは原点を表します。情報の一部。
この質問に戻って、私たちは食べることと食べられることの関係に従って動物を分類することを検討します:xx例としてx匹の動物を取り上げ、仮想動物x + n x + nを紹介しますバツ+nはxxを意味しますx動物を食べる、仮想動物を紹介するx + 2 ∗ n x + 2 * nバツ+2∗nはxxを意味しますx食べる動物は、同じ種類の動物を同じコレクションに入れ、使用してメンテナンスを確認することができます。
セットのマージと検索の操作方法は次のとおりです。
指定されたxとyが同じ場合、xxをマージします。x和yyyが配置されているセットは、x + n x + nをマージしますバツ+n和y + n y + nY+nがどこにあるかを設定し、x + 2 ∗ n x + 2 * nをマージしますバツ+2∗n和y + 2 ∗ n y + 2 * nY+2∗nが配置されているコレクション。
嘘を判断する:与えられた言葉でxxを表現するx和yyxxが以前に取得された場合、 yは例と同じ種類ですx和y + n y + nY+n(つまり、xxxとyyを食べるyの動物は同じ種類です)または、xxx和y + 2 ∗ n y + 2 * nY+2∗n(つまり、xとyが食べる動物は同じ種類です)は明らかに偽と判断できます。xxx吃yyyについても同じことが言えます。
このアルゴリズムの利点は、思考の難しさとコードの難しさを明らかに軽減しますが、それが支払う代償は、より多くのスペースとより大きな時間計算量定数であり、アプリケーションの範囲は重み付けされておらず、広範ではありません。
アルゴリズム2:加重および検索セット
非常に複雑なサイドライツなどを取得してから、モジュラスを取得して一連の式を設定します。だから、私は怠け者なので、ハハはこのようにプレイしませんでした。(しかし、私は自分の犯罪を補うために非常に良いブログを見つけました:解決策2
PS:最初にxxを判断するように注意してくださいxまたはyyyがnnより大きいnとxxxはyyに等しいyケース
コード
#include<iostream>
#include<cstdio>
#include<iomanip>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<bitset>
using namespace std;
int n,k,fa[150010],w,x,y,ans;
int find(int x){
if(fa[x]!=x)
return fa[x]=find(fa[x]);
else return fa[x];
}
int main(){
scanf("%d%d",&n,&k);
for(int i=1;i<=3*n;i++)//i+n表示天敌,i+2*n表示猎物
fa[i]=i;
while(k--)
{
scanf("%d%d%d",&w,&x,&y);
if(x>n||y>n)
{
ans++;
continue;
}
int xx=find(x),yy=find(y),sx=find(x+n),sy=find(y+n),tx=find(x+2*n),ty=find(y+2*n);
//xx,yy表示x和y的同类,sx,sy表示x和y的天敌,tx,ty表示x和y的猎物
if(w==1)
{
if(xx==sy||xx==ty){
//说是同类,却是天敌或猎物,就是假
ans++;
continue;
}
else fa[xx]=yy,fa[sx]=sy,fa[tx]=ty;
}
if(w==2)
{
if(xx==yy||sx==yy)//说是x吃y,却是同类或y吃x,就是假
{
ans++;
continue;
}
else fa[xx]=sy,fa[sx]=ty,fa[tx]=yy;//x的同类是y的天敌,x的天敌是y的猎物,x的猎物是y的同类
}
}
printf("%d",ans);
}