食物链 noj207
#include<stdio.h> int fa[50005]={0}; int rank[50005]={0}; int n; void initial() { for ( int i=1;i<=n;i++) { fa[i]=i; rank[i]=0; } } int getfather( int x) { if (x==fa[x]) return x; int oldfa = fa[x]; fa[x]=getfather(fa[x]); rank[x]=(rank[x]+rank[oldfa])%3; //用向量的形式很快就可以看出来 return fa[x]; } void unionset( int r, int x, int y) { int fx,fy; fx=getfather(x); fy=getfather(y); if (fx==fy) return ; fa[fx]=fy; rank[fx]=(rank[y]+r-rank[x]+3)%3; // 这里同样可以用向量来推公式。另外需要注意的是,这里只更新了fx的rank值,而fx的儿子的rank值都没有更新会不会有问题。其实不碍事,由于我们每次输入一组数据我们都对x和y进行了getfather的操作(x>n || y>n ……)的除外。在执行getfather的操作时,在回溯的过程中就会把fx的儿子的rank值都更新了。 return ; } int istrue( int d, int x, int y) { int fx,fy,r; if (x>n || y>n || ((x==y)&&(d==2)) ) return 0; fx=getfather(x); fy=getfather(y); if (fx!=fy) return 1; else { if (rank[x]==((d-1)+rank[y])%3) return 1; // 这个公式可以用向量来推:如果( f(x,y) + f(y,father[y]))% 3 == f(x,father[x]) 则是正确的,否则是错的。这个形式可以用向量来表示,就是判断这个向量加法对不对 x--->y + y---> fx(fy) 是否等于 x--->fx(fy) else return 0; } } int main() { int k,i,x,y,d; int ans=0; scanf ( "%d%d" ,&n,&k); initial(); for (i=1;i<=k;i++) { scanf ( "%d%d%d" ,&d,&x,&y); if ( !istrue(d,x,y) ) ans++; else unionset(d-1,x,y); } printf ( "%d\n" ,ans); return 0; } |
对于rank[]的值用向量求,不明白,有懂的给讲解一下!谢谢啦!
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步