首页 > 代码库 > BZOJ 3362: [Usaco2004 Feb]Navigation Nightmare 导航噩梦
BZOJ 3362: [Usaco2004 Feb]Navigation Nightmare 导航噩梦
Description
给你每个点与相邻点的距离和方向,求两点间的曼哈顿距离. \(n \leqslant 4\times 10^4\) .
Sol
加权并查集.
像向量合成一样合并就可以了,找 \(f[x]\) 的时候需要先记录现在的父节点,然后更新他新的父节点.
Code
/************************************************************** Problem: 3362 User: BeiYu Language: C++ Result: Accepted Time:80 ms Memory:3712 kb****************************************************************/ #include<cstdio>#include<algorithm>#include<iostream>using namespace std; typedef pair< int,int > pr;#define abs(x) ((x)<0 ? -(x) : (x) )#define mpr make_pair#define debug(a) cout<<#a<<"="<<a<<" "const int N = 40005; int n,m,k;int f[N],ans[N];pr g[N];struct Q{ int a,b,c,d; }q[N],qq[N]; inline int in(int x=0,char ch=getchar()){ while(ch>‘9‘ || ch<‘0‘) ch=getchar(); while(ch>=‘0‘ && ch<=‘9‘) x=(x<<3)+(x<<1)+ch-‘0‘,ch=getchar();return x ;}inline char read(char ch=getchar()){ while(ch>‘Z‘ || ch<‘A‘) ch=getchar();return ch; }pr operator + (const pr &a,const pr &b){ return mpr(a.first+b.first,a.second+b.second); }pr operator += (pr &a,const pr &b){ return a=a+b; }pr operator - (const pr &a,const pr &b){ return mpr(a.first-b.first,a.second-b.second); }pr operator -= (pr &a,const pr &b){ return a=a-b; } int cmp1(const Q &x,const Q &y){ return x.c<y.c; }int cmp2(const Q &x,const Q &y){ return x.d<y.d; }int find(int x){ if(f[x] == x) return x; int t=f[x];f[x]=find(f[x]); g[x]+=g[t];return f[x];}void work(int u,int v,int w,char d){ int r1=find(u),r2=find(v);// debug(r1),debug(r2)<<endl;// cout<<u<<" "<<v<<" "<<w<<" "<<d<<endl;// cout<<"qwq"<<endl; if(r1!=r2) switch(d){ case ‘N‘:f[r1]=r2,g[r1]=g[v]+mpr(0,w)-g[u];break; case ‘W‘:f[r1]=r2,g[r1]=g[v]+mpr(-w,0)-g[u];break; case ‘S‘:f[r1]=r2,g[r1]=g[v]+mpr(0,-w)-g[u];break; default:f[r1]=r2,g[r1]=g[v]+mpr(w,0)-g[u];break; }// for(int i=1;i<=n;i++) cout<<find(i)<<":("<<g[i].first<<","<<g[i].second<<") ";cout<<endl;}int main(){// freopen("in.in","r",stdin); n=in(),m=in(); for(int i=1;i<=n;i++) f[i]=i; for(int i=1;i<=m;i++) qq[i].a=in(),qq[i].b=in(),qq[i].c=in(),qq[i].d=read(); k=in();for(int i=1;i<=k;i++) q[i].a=in(),q[i].b=in(),q[i].c=in(),q[i].d=i; sort(q+1,q+k+1,cmp1);// for(int i=1;i<=m;i++) work(qq[i].a,qq[i].b,qq[i].c,qq[i].d);// for(int i=1;i<=n;i++) cout<<find(i)<<" ("<<g[i].first<<","<<g[i].second<<")\n"; for(int i=1,j=1,u,v,r1,r2;i<=k;i++){ for(;j<=q[i].c && j<=n;++j) work(qq[j].a,qq[j].b,qq[j].c,qq[j].d); u=q[i].a,v=q[i].b,r1=find(u),r2=find(v); if(r1==r2){// debug(u),debug(v),debug(g[u].first),debug(g[v].first),debug(g[u].second),debug(g[v].second)<<endl; ans[q[i].d]=abs(g[u].first-g[v].first)+abs(g[u].second-g[v].second); }else ans[q[i].d]=-1; }// for(int i=1;i<=n;i++) cout<<find(i)<<" ("<<g[i].first<<","<<g[i].second<<")\n"; for(int i=1;i<=k;i++) printf("%d\n",ans[i]); return 0;}
BZOJ 3362: [Usaco2004 Feb]Navigation Nightmare 导航噩梦
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。