标签:
10 10 1 2 150 3 4 200 1 5 270 2 6 200 6 5 80 4 7 150 8 9 100 4 8 50 1 7 100 9 2 100
2HintHint:(PS: the 5th and 10th requests are incorrect)
这是大神的解析,原来是向量的原理:
(1)弄清题意,找出出现冲突的位置,判断冲突很简单就是当两个人在同一行坐,同时他们到根节点的距离差值正好是他们之间的差值,此时就出现了冲突了。
(2)关键有两个地方,这也是并查集题目的难点,就是压缩集合,和求节点到根的距离。这里压缩集合就很简单了,一个通用的递归。求到跟的距离dist[a] += dist[tem]; dist[rb]=dist[a]+x-dist[b];注意这两行代码,这是核心代码,首先第一行是求出节点a到根的距离。第二行代码使用的是数学中向量计算的原理如图
图
#include<stdio.h> #include<string.h> #define M 50000+10 int x[M],rank[M];//rank表示的是到根节点的距离 int find(int k) { int temp=x[k]; if(x[k]==k) return k; x[k]=find(x[k]); rank[k]+=rank[temp]; return x[k]; } int merge(int a,int b,int m) { int fa=find(a); int fb=find(b); if(fa==fb){ if(rank[b]+m!=rank[a])//向量计算 return 0; else return 1; } x[fa]=fb; rank[fa]=rank[b]+m-rank[a];//用向量的运算法则计算 return 1; } int main() { int n,m,i,a,b,d; while(~scanf("%d%d",&n,&m)){ for(i=0;i<M;i++){ x[i]=i; rank[i]=0; } int count=0; while(m--){ scanf("%d%d%d",&a,&b,&d); if(!merge(a,b,d)) count++; } printf("%d\n",count); } return 0; }
标签:
原文地址:http://blog.csdn.net/ling_du/article/details/47133885