并查集经典题之POJ1984

来源:互联网 发布:日常口语话题topic知乎 编辑:程序博客网 时间:2024/06/05 04:48

题意:依据n个Famr之间有限的连接关系,求解指定两个Farm之间的Manhattan distance

分析:

1.k个Query依据时间点的顺序输入

2.对于输入的每一个连接关系,动态更新合并树的相对坐标。

//Date:     2015.04.21//Time:     125ms//Memory:   1564k#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int MAX=40005;int sum[MAX];int n,m,k;struct Farm{    int x,y,tree,next;}farms[MAX];struct Information{    int f1,f2,dx,dy;}data[MAX];void Update(int t1,int t2,int dx,int dy){    int i=t2,p;    while(~i){       farms[i].tree=t1;       farms[i].x += dx;       farms[i].y += dy;       p=i;i=farms[i].next;    }    farms[p].next=farms[t1].next;    farms[t1].next=t2;    sum[t1]=sum[t1]+sum[t2]+1;}void init(){    memset(data,0,sizeof(data));    memset(sum,0,sizeof(sum));    memset(farms,0,sizeof(farms));    for(int i=1;i<=n;i++){       farms[i].tree=i;       farms[i].next=-1;    }}int main(){    int i,j,t,len,f1,f2,t1,t2;    char dir;    scanf("%d%d",&n,&m);    init();    for(i=0;i<m;i++){        scanf("%d %d %d %c",&data[i].f1,&data[i].f2,&len,&dir);        switch(dir){            case 'E':data[i].dx= len;break;            case 'S':data[i].dy=-len;break;            case 'W':data[i].dx=-len;break;            case 'N':data[i].dy= len;break;        }    }    scanf("%d",&k);    for(j=i=0;i<k;i++){        scanf("%d %d %d",&f1,&f2,&t);        for(;j<t;j++){            t1=farms[data[j].f1].tree;t2=farms[data[j].f2].tree;            if(sum[t1]>=sum[t2])                Update(t1,t2,farms[data[j].f1].x+data[j].dx-farms[data[j].f2].x,farms[data[j].f1].y+data[j].dy-farms[data[j].f2].y);            else                Update(t2,t1,farms[data[j].f2].x-data[j].dx-farms[data[j].f1].x,farms[data[j].f2].y-data[j].dy-farms[data[j].f1].y);        }        t1=farms[f1].tree;t2=farms[f2].tree;        if(t1!=t2)            printf("-1\n");        else            printf("%d\n",abs(farms[f1].x-farms[f2].x)+abs(farms[f1].y-farms[f2].y));    }    return 0;}

0 0
原创粉丝点击