题目链接 Acwing 240 食物链 https://www.acwing.com/problem/content/242/
我写的代码我看不出来逻辑问题。但是输出结果就是错的。想问一下逻辑问题到底错在哪里?
错误的代码:
#include<iostream>
using namespace std;
const int N=50010;
int p[N],d[N];
int find(int x)
{
if(p[x]!=x)//如果x不是根节点
{
int t=find(p[x]);//递归找到根节点
d[x]+=d[p[x]];//递归一直加,最后结果就是x到根节点的距离
p[x]=t;//更新p[x]的根节点
}
return p[x];
}
int main()
{
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)
p[i]=i;
int res=0;
while(m--)
{
int k,x,y;
cin>>k>>x>>y;
if(x>n||y>n) res++;
else
{
int px=find(x),py=find(y);
if(k==1)
{
if(px==py)//px == py:表示节点 x 和 y 在同一个连通分量中。换句话说,x 和 y 具有相同的根节点。
if((d[x]-d[y])%3)//判断节点 x 和 y 之间的相对关系是否符合给定的条件。
res++;
else if(px!=py)//px != py:表示节点 x 和 y 在不同的连通分量中,即它们具有不同的根节点。(也就是说,第一次出现这个信息,所以没有和前面违背的)
{
p[px]=py;//将节点 x 所在连通分量的根节点 px 的父节点设为 y 所在连通分量的根节点 py。这相当于将 x 所在的整个连通分量合并到 y 所在的连通分量中。
d[px]=d[y]-d[x];//在合并时,需要更新 d[px],使得 px 到其新根节点 py 的距离关系保持正确。
}
}
else
{
if(x==y) res++;
else if(px==py)
if((d[x]-d[y]-1)%3) res++;
else if(px!=py)
{
p[px]=py;
d[px]=d[y]+1-d[x];//
}
}
}
}
cout<<res;
return 0;
}
正确的代码:
#include<iostream>
using namespace std;
const int N = 50010;
int p[N], d[N];
int find(int x) {
if (p[x] != x) { // 如果x不是根节点
int t = find(p[x]); // 递归找到根节点
d[x] += d[p[x]]; // 递归一直加,最后结果就是x到根节点的距离
p[x] = t; // 更新p[x]的根节点
}
return p[x];
}
int main() {
int n, m;
cin >> n >> m;
for (int i = 1; i <= n; i++)
p[i] = i;
int res = 0;
while (m--) {
int k, x, y;
cin >> k >> x >> y;
if (x > n || y > n) {
res++; // x或y超过范围,记为假话
continue;
}
int px = find(x), py = find(y);
if (k == 1) {
if (px == py) { // 如果x和y在同一个连通分量中
if ((d[x] - d[y]) % 3) { // 检查x和y是否真的同类
res++;
}
} else { // 如果x和y不在同一个连通分量中
p[px] = py; // 合并两个连通分量
d[px] = d[y] - d[x]; // 更新距离关系
}
} else { // 说法2: X吃Y
if (x == y) {
res++; // x不能吃自己,记为假话
continue;
}
if (px == py) { // 如果x和y在同一个连通分量中
if ((d[x] - d[y] - 1) % 3) { // 检查x是否真的吃y
res++;
}
} else { // 如果x和y不在同一个连通分量中
p[px] = py; // 合并两个连通分量
d[px] = d[y] + 1 - d[x]; // 更新距离关系
}
}
}
cout << res << endl;
return 0;
}
就算是对比两种代码,我也看不出,错误的代码到底错在哪里。
求大佬解答!!