1、WA代码
思路:预先分好3类,对每一行数据进行分类和真话假话判断
WA原因:前面某些行的数据 需要依赖 后面某些行给的数据 才能进行分类
初步改正思路( 对于前面给的无法直接分类的数据进行记录,等遇到合适的数据再拿出来进行分类 数据给完还无法分类的列为假话 )
未改正代码
# include<iostream> # include<string> # include<string.h> # include<queue> # include<stdio.h> # include<math.h> #include <algorithm> using namespace std; #define MAX 50005 //int rank[MAX]; int pre[MAX]; int tot,n; int flag[3]; struct Node { int a,b,c; }node; queue<Node> q; void Init() { for(int i=1;i<=n+6;i++) //pre[n+1]表示A类动物 pre[n+2]表示B类动物 pre[n+3]表示C类动物 { pre[i] = i; //rank[i] = 1; } tot = 0; flag[0] = 0; //表示尚无A类动物 flag[1] = 0; flag[2] = 0; } int find(int x) { int p=x,t; while(pre[p]!=p) //x结点迭代往上寻找到祖宗结点 存储在p { p = pre[p]; } while(x != p) // 把x结点到其祖宗结点中 经过的所有结点 都直接连到 祖宗结点 { t = pre[x]; pre[x] = p; x = t; } return x; } void Unite(int x,int y) { x = find(x); y = find(y); if(x==y) return; pre[x] = y; /* if(rank[x]<rank[y]) //高度小的为子树 { pre[x] = y; } else { pre[y] = x; if(rank[x] == rank[y]) rank[x]++; } */ } void judge() { int ct=0; while(!q.empty()) { node = q.front(); int a,b,c; a = node.a; b = node.b; c = node.c; int fb,fc,f=0; fb = find(b); fc = find(c); //printf("%d %d %d %d %d %d\n",f,fb,fc,flag[0],flag[1],flag[2]); //printf("%d\n--------------------------------------\n",tot); if(ct>=40) break; if(b>n || c>n ||b<=0 || c<=0) //假话条件2判断 { tot++; q.pop(); continue; } if(a==2 && b==c) //假话条件3 =判断 { tot++; q.pop(); continue; } if(a==1) { if( fb==b && fc==c ) //b,c编号动物都是第一次出现 { for(int i=0;i<3;i++) //3个类别未满 { if(flag[i]==0) { //Unite(b,n+i+1); //Unite(c,n+i+1); pre[b] = n+i+1; pre[c] = n+i+1; flag[i] = 1; f = 1; q.pop(); break; } } if(f==1) continue; //类别已满 q.push(node); ct++; } else if(fb==b && fc!=c) //b编号动物第一次出现,c编号动物已有分类 { pre[b] = fc; flag[fc-n-1] = 1; q.pop(); continue; } else if(fb!=b && fc==c) //c编号动物第一次出现,b编号动物已有分类 { pre[c] = fb; flag[fb-n-1] = 1; q.pop(); continue; } else //b,c编号动物都已分类 { if(fb!=fc) //出现矛盾 { tot++; q.pop(); continue; } } } else { //printf("%d %d",b,c); if( fb==b && fc==c ) //b,c编号动物都是第一次出现 { //printf("sddsgfdg"); for(int i=0;i<3;i++) //3个类别未满 { int j = (i+1)%3; if(flag[i]==0 && flag[j]==0) { //Unite(b,n+i+1); //Unite(c,n+j+1); pre[b] = n+i+1; pre[c] = n+j+1; flag[i] = 1; flag[j] = 1; f = 1; q.pop(); break; } } if(f==1) continue; //类别已满 q.push(node); ct++; } else if(fb==b && fc!=c) //b编号动物第一次出现,c编号动物已有分类 { if(fc==n+1) { pre[b] = n+3; //Unite(b,n+3); flag[2] = 1; q.pop(); continue; } else if(fc==n+2) { pre[b] = n+1; //Unite(b,n+1); flag[0] = 1; q.pop(); continue; } else if(fc==n+3) { pre[b] = n+2; //Unite(b,n+2); flag[1] = 1; q.pop(); continue; } } else if(fb!=b && fc==c) //c编号动物第一次出现,b编号动物已有分类 { if(fb==n+1) { pre[c] = n+2; //Unite(c,n+2); flag[1] = 1; q.pop(); continue; } else if(fb==n+2) { pre[c] = n+3; //Unite(c,n+3); flag[2] = 1; q.pop(); continue; } else if(fb==n+3) { pre[c] = n+1; //Unite(c,n+1); flag[0] = 1; q.pop(); continue; } } else //b,c编号动物都已分类 { if(fb-fc==-1 ) { q.pop(); continue; } else if(fb-fc==2 ) { q.pop(); continue; } tot++; q.pop(); continue; } } } while(!q.empty()) { tot++; q.pop(); } } int main() { int k; scanf("%d %d",&n,&k); Init(); int i,j; for(i=0;i<k;i++) { int a,b,c; scanf("%d %d %d",&a,&b,&c); node.a = a; node.b = b; node.c = c; q.push(node); //printf("%d\n---------------------------\n",tot); } judge(); printf("%d",tot); return 0; }
2、
正确思路:不按照捕食关系进行细致分类,而是按照动物间存在关系就分为一类,用relation表示结点与父节点的关系
扫描二维码关注公众号,回复:
2838956 查看本文章