首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

并查集习题-poj 1984

2012-09-03 
并查集练习---poj 1984usaco的月赛题。记录两个点之间x方向和y方向的相对距离,用并查集维护。若与poj 1182食

并查集练习---poj 1984

usaco的月赛题。

记录两个点之间x方向和y方向的相对距离,用并查集维护。

若与poj 1182食物链进行比较,便会发现路径压缩部分,集合合并部分的相似点。

所以并查集不难,是有一定套路可循的。大家一定要好好总结。

【代码】

#include <iostream>#include <cstring>#include <string>#include <cstdio>#include <algorithm>using namespace std;const int N=40005,K=10005;struct node{    int x,y,idx,n;}a[K];int x[N],y[N],dx[N],dy[N],rx[N],ry[N],ans[K],fa[N];int n,m,k;int find(int x){    if (fa[x]==x) return x;    int t=fa[x];    fa[x]=find(fa[x]);    rx[x]+=rx[t];    ry[x]+=ry[t];    return fa[x];}int cmp(node a,node b){    return a.idx<b.idx;}int main(){    int i,j,d,fx,fy;    char c;    freopen("in","r",stdin);    scanf("%d%d",&n,&m);    for (i=1;i<=n;i++)    {        fa[i]=i;        rx[i]=ry[i]=0;    }    for (i=1;i<=m;i++)    {        scanf("%d%d%d %c",&x[i],&y[i],&d,&c);        switch(c)        {            case 'W':dx[i]=-d;dy[i]=0;break;            case 'S':dx[i]=0;dy[i]=-d;break;            case 'E':dx[i]=d;dy[i]=0;break;            case 'N':dx[i]=0;dy[i]=d;break;        }    }    scanf("%d",&k);    for (i=1;i<=k;i++)    {        scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].idx);        a[i].n=i;    }    sort(a+1,a+k+1,cmp);    j=1;    for (i=1;i<=k;i++)    {        for (;j<=a[i].idx;j++)        {            fx=find(x[j]);fy=find(y[j]);            fa[fy]=fx;            rx[fy]=rx[x[j]]-rx[y[j]]-dx[j];            ry[fy]=ry[x[j]]-ry[y[j]]-dy[j];        }        if (find(a[i].x)!=find(a[i].y))            ans[a[i].n]=-1;        else            ans[a[i].n]=abs(rx[a[i].x]-rx[a[i].y])+abs(ry[a[i].x]-ry[a[i].y]);    }    for (i=1;i<=k;i++)        printf("%d\n",ans[i]);}



热点排行