土豪的时代 | ||||||
| ||||||
Description | ||||||
土豪圈有一个习惯:从来不告诉别人自己到底有多少钱。但他们总是喜欢和其他土豪比较,来看看谁更土豪。于是每每几天,就会爆出一些关于土豪资产的消息,比如A土豪比B土豪多了3254万,C土豪比D土豪少2124万等等,从这些消息中也很容易推测出某两个土豪之间的资产关系。小破觉得和土豪交朋友是件非常愉快的事,但她想知道,某两个土豪,哪个更土豪。你能帮帮她么。 | ||||||
Input | ||||||
多组测试数据 每组测试数据第一行有一个数n。( n<=100000 ) 接下来有n行,每行包含一种操作。 操作分为两种: 1 a b m :表示a比b多m万元。 2 a b: 表示询问a比b多多少万元。 (0 < a,b < n) (0 <= m <= 1000) 评测数据保证合法。 | ||||||
Output | ||||||
对于每次的询问操作,输出其结果。当结果未知时,输出"?"。 | ||||||
Sample Input | ||||||
5 1 1 2 10 2 1 3 1 3 4 10 1 2 3 10 2 4 1 | ||||||
Sample Output | ||||||
? -30 | ||||||
Source | ||||||
哈尔滨理工大学第五届ACM程序设计竞赛(热身) |
这个题其实可以用floyd递推关系得到结果,把经济差看成距离差,但是因为n太大、、、、大家懂的、、、、dijkstra没有floyd那样,想得到什么结果就得到什么结果,所以这个题还是老老实实的用带权并查集来做。
这个题一共有两个操作,那么我们就着重来说这两个操作:
1、查询操作。
这里我们规定,sum【x】代表x到fx的距离为sum【x】、(fx是x的祖先)查询操作中,如果x和y的祖先不同,也就是说x,y不在一个集合中,那么我们就无法确定他们的关系,这个时候输出“?”、相反,如果x,y的祖先相同,那么我们可以画一条线段来理解:
那么问你x到y的距离,那还看不出来吗?sumx-sumy即可、
这里我们解决了查询的问题,我们相应贴上代码:
int x,y;
scanf("%d%d",&x,&y);
int X=find(x);
int Y=find(y);
if(X!=Y)
{
printf("?\n");
}
else
{
printf("%d\n",sum[y]-sum[x]);
}
2、连接
如果我们有查询的操作,当然就要有连接的操作,这里相对稍微复杂些、
首先和普通的merge操作一样,找到fx,fy,如果fx!=fy,我们开始连接操作、
这里我的习惯是让F【fy】=fx,所以我们这里在连接的时候是这样连接的,那么权值如何变化呢?我们这里对应画出一个图就能解决这个问题:
我们这里所求的值如图所示,那么我们很容易找到这样的等式:
sumy+所求值==val+sumx
那么所求值=val+sumx-sumy
同样很容易就解决了问题,这里我们也对应上代码:
int x,y,val;
scanf("%d%d%d",&x,&y,&val);
int X=find(x);
int Y=find(y);
if(X!=Y)
{
sum[Y]=val-sum[y]+sum[x];
f[Y]=X;
}
最后上完整的AC代码:
这样,一道带权并查集就解决了:
#include<stdio.h>
#include<string.h>
using namespace std;
int f[1000010];
int sum[1000010];
int find(int x)
{
if(x!=f[x])
{
int pre=f[x];//pre是x的一个父节点。
f[x]=find(f[x]);//递归找祖先。
sum[x]+=sum[pre];//路径压缩部分。
}
return f[x];
}
int main()
{
int n;
while(~scanf("%d",&n))
{
for(int i=0;i<=n;i++)
{
f[i]=i;
sum[i]=0;
}
int op;
while(n--)
{
scanf("%d",&op);
if(op==1)
{
int x,y,val;
scanf("%d%d%d",&x,&y,&val);
int X=find(x);
int Y=find(y);
if(X!=Y)
{
sum[Y]=val-sum[y]+sum[x];
f[Y]=X;
}
}
else
{
int x,y;
scanf("%d%d",&x,&y);
int X=find(x);
int Y=find(y);
if(X!=Y)
{
printf("?\n");
}
else
{
printf("%d\n",sum[y]-sum[x]);
}
}
}
}
}