时空隧道:
http://poj.org/problem?id=1182
先吐槽发我觉得这道题真心坑......
我先用的while(~scanf())输入一直wa,各种debug找不出
最后让学长帮忙。。然后我又一句一句的对照过去。。。发现真心除了那个while那不一样其他都一样
去掉就AC了!!!X!
大概就是用距离维护关系 或者说是向量 如果2 a b ,a到b的距离为1, 2 c d c到d的距离为1,
2 c a 的时候,c->a的距离为1 此时 注意是向量 所以 d->a=d->c+c->a=-1+1=0;
这样就维护了。 d->b的距离自然=a->b+c->a+d->c;
把上面的文字整理成图像更清晰一些。
因为最多也就是只有a b 同类 dis=0 被吃 1 吃2( 2==(-1+3)%3 ) 所以用%3来维护
好吧。。。说的比较混乱 代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=50010;
int bleg[maxn],rank[maxn];
int n,m;
void Init()
{
for(int i=0;i<=n;i++)
bleg[i]=i,rank[i]=0;
}
int Find(int x)
{
int y=x,cnt=0;
while(x!=bleg[x])
{
cnt+=rank[x];
x=bleg[x];
}
while(y!=bleg[y])
{
int tmp=rank[y];
int px=bleg[y];
rank[y]=cnt%3;
bleg[y]=x;
cnt-=tmp;
y=px;
}
return x;
}
void Union(int x,int y,int value)
{
int pa=Find(x),pb=Find(y);
bleg[pa]=pb;
rank[pa]=(rank[y]-rank[x]+value+3)%3;
}
int main()
{
// while(~scanf("%d%d",&n,&m))
//{
int sum=0;
int a,b,c;
scanf("%d%d",&n,&m);
Init();
for(int i=0;i<m;i++)
{
scanf("%d%d%d",&c,&a,&b);
if(a>n || b>n || (c==2 && a==b))
{
sum++;
continue;
}
int pa=Find(a),pb=Find(b);
if(pa==pb)
{
if((rank[a]-rank[b]+3)%3!=c-1)
sum++;
}
else
Union(a,b,c-1);
}
printf("%d\n",sum);
//}
return 0;
}