(说实话这篇写的我自己都快看不懂,肯定会重写的!
题意和思路:
中文题意,我简单提一下:
A->B,B->C,C->A。A吃B,B吃C,C吃A,这是循环的。
r[] 数组保存的是 该节点和祖先节点的关系:
0-和祖宗节点同类;
1-吃祖宗节点;
2-被祖宗节点吃。
输入c, a, b表示:
if(c==1) a和b节点同类;
if(c==2) a吃b。
注意:c-1就和最上面数字的数字表示相同的意思。
输出: 假语句的数量
题目链接:点击做题
AC代码:
把多组输入去掉就能AC,md,poj多组输入这个坑好烦啊啊啊啊!!!
#include<bits/stdc++.h>
#define mm1(a) memset((a),-1,sizeof((a)))
#define mm0(a) memset((a),0,sizeof((a)))
#define mmx(a) memset((a),0x3f,sizeof((a)))
using namespace std;
typedef long long LL;
const int N = 50005;
const int INF = 1e9;
const int mod = 1e9 + 7;
#define DEBUG
int n,m;
int fa[N];
int r[N];
int Fi(int x){
if(x!=fa[x]){
int t=fa[x];
fa[x]=Fi(fa[x]);
r[x]=(r[x]+r[t])%3;
}
return fa[x];
}
void un(int a,int b,int c){
int pa=Fi(a),pb=Fi(b);
fa[pb]=pa;
r[pb]=(r[a]+c-1-r[b]+3)%3;
Fi(a),Fi(b);
}
int main(){
while(~scanf("%d%d",&n,&m)){
mm0(r);
for(int i=0;i<=n;++i)fa[i]=i;
int ans=0,a,b,c;
for(int h=0;h<m;++h){
scanf("%d%d%d",&c,&a,&b);
if(a>n||b>n||(c==2&&a==b)){
ans++;continue;
}
int pa=Fi(a),pb=Fi(b);
if(pa!=pb){
un(a,b,c);
}else{
if(r[b]!=(r[a]+c-1)%3)ans++;
}
}
printf("%d\n",ans );
}
return 0;
}
并查集的写法:
//int Fi(int x){
// return fa[x]==x?x:fa[x]=Fi(fa[x]);
//}
inline int Fi(int x){
int t=x,p;
while(x!=fa[x])x=fa[x];
while(t!=x)p=fa[t],fa[t]=x,t=p;
return x;
}
int find1(int x){
return x==fa[x]?x:fa[x]=find1(fa[x]);
}
inline int find2(int x){
return x==fa[x]?x:fa[x]=find2(fa[x]);
}
inline int find3(int x){
while(x!=fa[x])x=fa[x]=fa[fa[x]];return x;
}
inline int find4(int x){
int se=0;st[0]=x;
while(fa[x]!=x)st[++se]=x=fa[x];
while(se)fa[st[--se]]=x;
return x;
}
inline int find5(int x){
int t=x,p;
while(x!=fa[x])x=fa[x];
while(t!=x)p=fa[t],fa[t]=x,t=p;
return x;
}
int find6(int x){
return 0>fa[x]?x:fa[x]=find6(fa[x]);
}
inline int find7(int x){
return 0>fa[x]?x:fa[x]=find7(fa[x]);
}
inline int find8(int x){
while(fa[x]>=0&&fa[fa[x]]>=0)x=fa[x]=fa[fa[x]];return fa[x]<0?x:fa[x];
}
更多请访问:https://mcfx.us/archives/176/
int find(int x){
int g = x , h;
while(p[x] != x) x = p[x];
while(p[g] != x){
h = p[g];
p[g] = x;
g = h;
}
return x;
}
我喜欢的写法:
int Fi(int x){
return fa[x]==x?x:fa[x]=Fi(fa[x]);
}
inline int Fi(int x){
int t=x,p;
while(x!=fa[x])x=fa[x];
while(t!=x)p=fa[t],fa[t]=x,t=p;
return x;
}
inline int find3(int x){
while(x!=fa[x])x=fa[x]=fa[fa[x]];return x;
}
inline int find7(int x){
return 0>fa[x]?x:fa[x]=find7(fa[x]);
}
inline int find8(int x){
while(fa[x]>=0&&fa[fa[x]]>=0)x=fa[x]=fa[fa[x]];return fa[x]<0?x:fa[x];
}