美文网首页
POJ1984(Navigation Nightmare)

POJ1984(Navigation Nightmare)

作者: kimoyami | 来源:发表于2018-10-31 08:51 被阅读4次

链接:https://vjudge.net/problem/POJ-1984
思路:感觉kuangbin系列的并查集都是一个套路啊,维护与根节点的关系,不管是可传递的模加法还是距离实质都是一样的,本题我的做法是先把所有道路全部读入保存,然后再把所有查询读入保存,按照时间先后排序,然后遍历所有查询,每次查询前先把该时间点之前的所有道路都用并查集关系建立起来(在x,y上分别维护关系),然后查询,如果二者的根节点相同说明之间有路,返回二者x,y距离差的绝对值的和即可,否则一定没有道路,返回-1,最后再按照之前的输入顺序输出答案即可。
代码:

#include<cstdio>
#include<algorithm>
using namespace std;

const int maxn = 400000;
int par[maxn];
int relx[maxn];
int rely[maxn];
int n,m,q;

int getroot(int a){
    if(par[a]==a)return a;
    int px = par[a];
    par[a] = getroot(par[a]);
    relx[a] = relx[a] + relx[px];
    rely[a] = rely[a] + rely[px];
    return par[a];  
}

struct query{
    int a,b,t,id,res;
    bool operator<(const query& r)const{
        return t<r.t;
    }
}ask[maxn];

bool cmp(const query &r1,const query &r2){
    return r1.id<r2.id;
}

struct change{
    int a,b,dx,dy;
}cc[maxn];

int main(){
    while(~scanf("%d%d",&n,&m)){
        for(int i=0;i<=n;i++){
            par[i] = i;
            relx[i] = rely[i] = 0;
        }
        for(int i=0;i<m;i++){
            char ch[10];
            int d = 0;
            scanf("%d%d%d%s",&cc[i].a,&cc[i].b,&d,ch);
            if(ch[0]=='E')cc[i].dy = d,cc[i].dx = 0;
            else if(ch[0]=='W')cc[i].dy = -d,cc[i].dx = 0;
            else if(ch[0]=='N')cc[i].dx = -d,cc[i].dy = 0;
            else if(ch[0]=='S')cc[i].dx = d,cc[i].dy = 0;
        }
        scanf("%d",&q);
        for(int i=0;i<q;i++){
            scanf("%d%d%d",&ask[i].a,&ask[i].b,&ask[i].t);
            ask[i].id = i;
        }
        sort(ask,ask+q);//按照时间先后顺序排序
        int nowi = 0;
        for(int i=0;i<q;i++){
            while(nowi+1<=ask[i].t){//将该时间点前的所有道路建立处理
                int a = cc[nowi].a;
                int b = cc[nowi].b;
                int p1 = getroot(a);
                int p2 = getroot(b);
                if(p1==p2)continue;
                par[p2] = p1;
                //x和y上分别维护关系
                relx[p2] = -relx[b]-cc[nowi].dx+relx[a];
                rely[p2] = -rely[b]-cc[nowi].dy+rely[a];
                nowi++;
            }
            int a = ask[i].a;
            int b = ask[i].b;
            int p1 = getroot(a);
            int p2 = getroot(b);
            if(p1==p2){
                ask[i].res = abs(relx[a]-relx[b])+abs(rely[a]-rely[b]);
            }
            else ask[i].res = -1;
        }
        sort(ask,ask+q,cmp);//还原原来的输入顺序
        for(int i=0;i<q;i++){
            printf("%d\n",ask[i].res);
        }
    }
    return 0;
}

相关文章

  • POJ1984(Navigation Nightmare)

    链接:https://vjudge.net/problem/POJ-1984思路:感觉kuangbin系列的并查集...

  • nightmare

    昨晚,梦到范丹了。 在父母家,床上,我们在亲热。 她不如过去那般纵情,但依旧愿意配合。 事后,我突然想起来,其实我...

  • The Nightmare ②

    日,内,卧室 姚湄惊醒,跑出卧室。喝了两杯白水,心跳稍稍有些平稳。白鹜在客厅看书。 午后,阴天,客厅 白鹜:又做噩...

  • Nightmare

    你啊,你啊,我心心念念的可全都是你啊。 我知道自己喜欢的爱的是你,可你的样子一直都是一团谜,如同儿时绵延不见尽头的...

  • nightmare

    谢谢你给我一个四季分明。

  • Nightmare

    穷其一生,逃不过一个梦。

  • nightmare

    前几天想多陪陪爸妈回家住了差不多三天,一般都是住一天就走的,一切看似和谐,然而我整个人无望到了极点,那种感觉无法...

  • nightmare

    enmmm,梦魇,~enmmm,梦魇,~enmmm,梦魇,~enmmm,梦魇,~ 嗯嗯嗯? 好像哪里不对,,额额...

  • nightmare

    一个人的夜晚胡思乱想,所有的负面情绪都在侵蚀着我的意志力失望,沮丧,悲观,流泪那些自以为是的坚持,原来在对方不在乎...

  • nightmare

    last night, i had a nightmare. i was bitten by a poisonou...

网友评论

      本文标题:POJ1984(Navigation Nightmare)

      本文链接:https://www.haomeiwen.com/subject/bysotqtx.html