首页 > 代码库 > POJ 1182 食物链【并查集】
POJ 1182 食物链【并查集】
题目链接:http://poj.org/problem?id=1182
此题利用并查集解决。
对于每只动物i创建3个元素i-A,i-B,i-C,并用这3*N个元素建立并查集。
1·i-x表示“i属于种类x”
2·并查集你的每一组表示组内所有元素代表的情况同时发生或不发生。
对于每一条信息,只需要按照下列操作即可:
1.第一种:x,y同类,合并x-A和y-A、x-B和y-B、x-C和y-C。
2.第二种:x吃y,,,合并x-A和y-B、x-B和y-C、x-C和y-A。
当然,在合并之前,需要判断合并是否会产生矛盾,若有矛盾,则结果+1;
代码:
#include <iostream> #include <cstdio> using namespace std; #define MAX_K 100000 int par[MAX_K],rank[MAX_K]; int t[MAX_K],x[MAX_K],y[MAX_K]; //以下是并查集的函数 void init(int n) { for(int i=0;i<n;i++) { par[i]=i; rank[i]=0; } } int find(int x) { if(par[x]==x) return x; else return par[x]=find(par[x]); } void unite(int x,int y) { x=find(x); y=find(y); if(x==y) return ; if(rank[x]<rank[y]) par[x]=y; else { par[y]=x; if(rank[x]==rank[y]) rank[x]++; } } bool same(int x,int y) { return find(x)==find(y); } int main() { int n,k,t,x,y; int ans=0; scanf("%d%d",&n,&k); init(n*3); for(int i=0;i<k;i++) { scanf("%d%d%d",&t,&x,&y); x--,y--; if(x<0||x>=n||y<0||y>=n) { ans++; continue; } if(t==1) //xy是同类 { if(same(x,y+n)||same(x,y+2*n)) { ans++; } else { unite(x,y); unite(x+n,y+n); unite(x+2*n,y+2*n); } } else //x吃y { if(same(x,y)||same(x,y+n*2)) { ans++; } else { unite(x,y+n); unite(x+n,y+2*n); unite(x+2*n,y); } } } printf("%d\n",ans); return 0; }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。