NYOJ 食物链(WA)

时间:2022-12-02 03:21:49

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[];
struct Node
{
int a,b,c;
}node;
queue<Node> q;
void Init()
{
for(int i=;i<=n+;i++) //pre[n+1]表示A类动物 pre[n+2]表示B类动物 pre[n+3]表示C类动物
{
pre[i] = i;
//rank[i] = 1;
}
tot = ;
flag[] = ; //表示尚无A类动物
flag[] = ;
flag[] = ;
}
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=;
while(!q.empty())
{ node = q.front();
int a,b,c;
a = node.a;
b = node.b;
c = node.c;
int fb,fc,f=;
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>=) break; if(b>n || c>n ||b<= || c<=) //假话条件2判断
{
tot++;
q.pop();
continue;
}
if(a== && b==c) //假话条件3 =判断
{
tot++;
q.pop();
continue;
}
if(a==)
{
if( fb==b && fc==c ) //b,c编号动物都是第一次出现
{
for(int i=;i<;i++) //3个类别未满
{
if(flag[i]==)
{
//Unite(b,n+i+1);
//Unite(c,n+i+1);
pre[b] = n+i+;
pre[c] = n+i+;
flag[i] = ;
f = ;
q.pop();
break;
}
}
if(f==) continue;
//类别已满
q.push(node);
ct++;
}
else if(fb==b && fc!=c) //b编号动物第一次出现,c编号动物已有分类
{
pre[b] = fc;
flag[fc-n-] = ;
q.pop();
continue;
}
else if(fb!=b && fc==c) //c编号动物第一次出现,b编号动物已有分类
{
pre[c] = fb;
flag[fb-n-] = ;
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=;i<;i++) //3个类别未满
{
int j = (i+)%;
if(flag[i]== && flag[j]==)
{
//Unite(b,n+i+1);
//Unite(c,n+j+1);
pre[b] = n+i+;
pre[c] = n+j+;
flag[i] = ;
flag[j] = ;
f = ;
q.pop();
break;
}
} if(f==) continue;
//类别已满
q.push(node);
ct++;
}
else if(fb==b && fc!=c) //b编号动物第一次出现,c编号动物已有分类
{
if(fc==n+)
{
pre[b] = n+; //Unite(b,n+3);
flag[] = ;
q.pop();
continue;
}
else if(fc==n+)
{
pre[b] = n+; //Unite(b,n+1);
flag[] = ;
q.pop();
continue;
}
else if(fc==n+)
{
pre[b] = n+; //Unite(b,n+2);
flag[] = ;
q.pop();
continue;
}
}
else if(fb!=b && fc==c) //c编号动物第一次出现,b编号动物已有分类
{
if(fb==n+)
{
pre[c] = n+; //Unite(c,n+2);
flag[] = ;
q.pop();
continue;
}
else if(fb==n+)
{
pre[c] = n+; //Unite(c,n+3);
flag[] = ;
q.pop();
continue;
}
else if(fb==n+)
{
pre[c] = n+; //Unite(c,n+1);
flag[] = ;
q.pop();
continue;
}
}
else //b,c编号动物都已分类
{
if(fb-fc==- )
{
q.pop();
continue;
}
else if(fb-fc== )
{
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=;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 ;
}

2、

正确思路:不按照捕食关系进行细致分类,而是按照动物间存在关系就分为一类,用relation表示结点与父节点的关系