【并查集】:poj1182,食物链
来源:互联网 发布:mac电脑usb接口没反应 编辑:程序博客网 时间:2024/05/01 11:07
关键是向量化的关系调整。
下面能过。
注意几点:
FindParent、用scanf别用cin。
# include<iostream># include<string.h># include<stdio.h>using namespace std;# define N 50010# define K 100005struct NODE{ int parent; int relation; //0表示和父节点同类,1表示被父节点吃(规定,让y指向x),2表示吃父节点 //(必须和d-1对应上) //若D=1,则表示X和Y是同类。 //若D=2,则表示X吃Y。};NODE node[N];void MakeSet(int n){ for(int i=1;i<=n;i++) { node[i].parent=i; node[i].relation=0; }}int FindParent(int x){ if(node[x].parent==x) { return x; } else { /* node[x].parent=FindParent(node[x].parent); node[x].relation=(node[x].relation+node[node[x].parent].relation)%3; //x->xp->xpp */ //can't use above codes, will WA int temp = node[x].parent; //路径压缩 node[x].parent = FindParent(temp); node[x].relation = (node[x].relation + node[temp].relation) % 3; //关系域更新 return node[x].parent; }}int Judge(int x, int y, int d){ int xp=FindParent(x); int yp=FindParent(y); if(xp==yp) //不需要合并,直接判断是否冲突 { if( d==1 && node[x].relation!=node[y].relation ) { return 1; } if( d==2 && ( (3+node[y].relation-node[x].relation)%3!=(d-1) ) ) { return 1; } } else { //先合并 node[yp].parent=xp; //再调整关系 //node[yp].relation=(-node[y].relation-(d-1)+node[x].relation+3)%3; node[yp].relation=(3-node[y].relation+(d-1)+node[x].relation)%3; //注意是,+(d-1),因为d-1之后,已经对应y->x的关系了(d表示x->y的关系) return 0; }}int main(){ int sum=0; int n,k,d,x,y,i; cin>>n>>k; MakeSet(n); for(i=1;i<=k;i++) { //cin>>d>>x>>y; scanf("%d%d%d",&d,&x,&y); //or TLE if( (x>n||y>n) || (x==y&&d==2) ) { sum++; } else { //sum+=Judge(x,y,d); int xp=FindParent(x); int yp=FindParent(y); if(xp==yp) //不需要合并,直接判断是否冲突 { if( d==1 && node[x].relation!=node[y].relation ) { //return 1; sum++; } if( d==2 && ( (3+node[y].relation-node[x].relation)%3!=(d-1) ) ) { //return 1; sum++; } } else { //先合并 node[yp].parent=xp; //再调整关系 //node[yp].relation=(-node[y].relation-(d-1)+node[x].relation+3)%3; node[yp].relation=(3-node[y].relation+(d-1)+node[x].relation)%3; //注意是,+(d-1),因为d-1之后,已经对应y->x的关系了(d表示x->y的关系) //return 0; } } } cout<<sum<<endl; return 0;}
没看出啊下面有什么问题,但是就是不AC。大神看到了指导一下。
# include<iostream># include<string.h># include<stdio.h>using namespace std;# define N 50010# define K 100005struct NODE{ int parent; int relation; //0表示和父节点同类,1表示被父节点吃(规定,让y指向x),2表示吃父节点 //(必须和d-1对应上) //若D=1,则表示X和Y是同类。 //若D=2,则表示X吃Y。};NODE node[N];void MakeSet(int n){ for(int i=1;i<=n;i++) { node[i].parent=i; node[i].relation=0; }}int FindParent(int x){ if(node[x].parent==x) { return x; } else { /* node[x].parent=FindParent(node[x].parent); node[x].relation=(node[x].relation+node[node[x].parent].relation)%3; //x->xp->xpp */ //can't use above codes, will WA int temp = node[x].parent; //路径压缩 node[x].parent = FindParent(temp); node[x].relation = (node[x].relation + node[temp].relation) % 3; //关系域更新 return node[x].parent; }}int Judge(int x, int y, int d){ int xp=FindParent(x); int yp=FindParent(y); if(xp==yp) //不需要合并,直接判断是否冲突 { if( d==1 && node[x].relation!=node[y].relation ) { return 1; } if( d==2 && ( (3+node[y].relation-node[x].relation)%3!=(d-1) ) ) { return 1; } } else { //先合并 node[yp].parent=xp; //再调整关系 //node[yp].relation=(-node[y].relation-(d-1)+node[x].relation+3)%3; node[yp].relation=(3-node[y].relation+(d-1)+node[x].relation)%3; //注意是,+(d-1),因为d-1之后,已经对应y->x的关系了(d表示x->y的关系) return 0; }}int main(){ int sum=0; int n,k,d,x,y,i; cin>>n>>k; MakeSet(n); for(i=1;i<=k;i++) { //cin>>d>>x>>y; scanf("%d%d%d",&d,&x,&y); //or TLE if( (x>n||y>n) || (x==y&&d==2) ) { sum++; } else { sum+=Judge(x,y,d); /* int xp=FindParent(x); int yp=FindParent(y); if(xp==yp) //不需要合并,直接判断是否冲突 { if( d==1 && node[x].relation!=node[y].relation ) { //return 1; sum++; } if( d==2 && ( (3+node[y].relation-node[x].relation)%3!=(d-1) ) ) { //return 1; sum++; } } else { //先合并 node[yp].parent=xp; //再调整关系 //node[yp].relation=(-node[y].relation-(d-1)+node[x].relation+3)%3; node[yp].relation=(3-node[y].relation+(d-1)+node[x].relation)%3; //注意是,+(d-1),因为d-1之后,已经对应y->x的关系了(d表示x->y的关系) //return 0; } */ } } cout<<sum<<endl; return 0;}
又做了一遍,过了:
#include <iostream>#include <stdio.h>using namespace std;#define N 50005struct NODE{ int par; int rel; //d=1,x和y同类 //d=2,x吃y //转换为d-1: //d-1=0,x和y同类 //d-1=1,父亲吃儿子(令y是x的儿子) //d-1=2,儿子吃父亲(令y是x的儿子)};NODE node[N];int FindPar(int x){ if(node[x].par==x) { return x; } else { int temp=node[x].par; node[x].par=FindPar(temp); node[x].rel=(node[x].rel+node[temp].rel)%3; return node[x].par; }}int main(){ int n,k,d,x,y,i,sum=0; cin>>n>>k; for(i=1;i<=n;i++) { node[i].par=i; node[i].rel=0; } for(i=1;i<=k;i++) { scanf("%d%d%d",&d,&x,&y); if( (x>n || y>n) || (d==2 && x==y) ) { sum++; } else { int xp=FindPar(x); int yp=FindPar(y); if(xp==yp) { if( d==1 && (node[x].rel!=node[y].rel) ) { sum++; } if( d==2 && (3+node[y].rel-node[x].rel)%3 != (d-1) ) { sum++; } } else { node[yp].par=xp; node[yp].rel=(3-node[y].rel+(d-1)+node[x].rel)%3; } } } cout<<sum<<endl; return 0;}
1 0
- 食物链 POJ1182 -- 并查集
- poj1182 食物链 (并查集)
- poj1182 并查集 食物链
- poj1182食物链 并查集
- 并查集-POJ1182食物链
- POJ1182 - 食物链 - 并查集
- 并查集 食物链 POJ1182
- poj1182 食物链(并查集)
- POJ1182 食物链 并查集
- Poj1182食物链 (并查集)
- POJ1182 食物链(并查集)
- 【并查集】:poj1182,食物链
- POJ1182 食物链(并查集)
- POJ1182 食物链 并查集
- poj1182 食物链[并查集]
- poj1182 食物链(并查集)
- POJ1182 食物链【并查集】
- poj1182食物链(种类并查集)
- leetcode笔记:Sort Colors
- iOS开发篇——UITextField
- Android Fragment 真正的完全解析(上)
- VirtualBox下的虚拟机的网络设置问题
- Pascal Costanza:极端片面的Lisp介绍
- 【并查集】:poj1182,食物链
- tcp与udp 的区别
- Service Android
- java zipoutputstream 的使用
- weiphp转移项目后,验证码不显示问题
- 高效批量插入大量数据----JDBC-4
- zabbix key总是not supported的解决方法
- 用delegate做值的回传
- Android Fragment 真正的完全解析(下)