NC25107. 小w的基站网络
描述
W城有n座基站,每座基站可用一个二维特征向量来表示,并且任意一座基站的特征向量均满足y>0。任意两座基站之间是否有单向传输数据的专线取决于这两座基站特征向量的叉积,当且仅当时,有一条从a基站到b基站传输数据的单向专线,专线的传输代价为这两座基站的叉积。反之如果,则代表不能从a基站向b基站传输数据。
输入描述
第一行输入一个正整数n表示有座基站。
接下来n行,每行两个整数x,y表示每个基站的特征向量,并且保证所有的特征向量均满足。
最后输入一个正整数k
表示小w所在的基站。
输出描述
输出共n行,依次表示小w所在的基站向各个基站传输数据的最小代价。如果小w所在的基站无法到达目标基站,则在该行输出一个"-1"来表示无法到达。
示例1
输入:
5 -1 1 -1 5 1 5 0 2 2 2 5
输出:
4 6 8 4 0
说明:
示例2
输入:
5 -1 1 -1 5 1 5 0 2 2 2 1
输出:
0 -1 -1 -1 -1
说明:
示例3
输入:
5 -2 2 2 2 1 1 -1 1 1 1 3
输出:
4 -1 0 2 -1
说明:
C++14(g++5.4) 解法, 执行用时: 806ms, 内存消耗: 40532K, 提交时间: 2020-02-01 19:49:13
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=1e6+5; int stk[N],top; ll dp[N]; struct node { ll x,y; int id; }a[N]; //极角排序 bool cmp(node a,node b) { ll tmp=a.x*b.y-a.y*b.x; if(tmp) return tmp>0; return a.x*a.x+a.y*a.y>b.x*b.x+b.y*b.y; } ll cross(node a,node b) { return a.x*b.y-a.y*b.x; } int main() { int n; scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%lld%lld",&a[i].x,&a[i].y); a[i].id=i; } sort(a+1,a+1+n,cmp); int flag,st; scanf("%d",&st); memset(dp,-1,sizeof dp); dp[st]=0; for(int i=1;i<=n;i++) { if(a[i].id==st) { flag=i; break; } } stk[++top]=flag; for(int i=flag+1;i<=n;i++) { if(cross(a[flag],a[i])==0) continue; while(top>1&&cross(a[stk[top-1]],a[stk[top]])==0)top--; while(top>1&&dp[a[stk[top]].id]+cross(a[stk[top]],a[i])>=dp[a[stk[top-1]].id]+cross(a[stk[top-1]],a[i]))--top; dp[a[i].id]=dp[a[stk[top]].id]+cross(a[stk[top]],a[i]); stk[++top]=i; } for(int i=1;i<=n;i++) printf("%lld\n",dp[i]); return 0; }
C++11(clang++ 3.9) 解法, 执行用时: 766ms, 内存消耗: 28804K, 提交时间: 2019-06-21 21:14:52
#include<bits/stdc++.h> #define fo(i,a,b)for(int i=a,_e=b;i<=_e;++i) #define fd(i,a,b)for(int i=b,_e=a;i>=_e;--i) #define nod(x,y) (nod){x,y} #define ll long long using namespace std; const int N=1e6+5; int n,k; int st[N],ss; ll ans[N],p[N]; struct nod{ int x,y,i; }b[N]; ll cj(nod a,nod b){ return (ll)a.x*b.y-(ll)a.y*b.x; } bool cmp(nod x,nod y){ ll t=cj(x,y); return t>0||t==0&&x.y>y.y; } bool pd(nod x,nod y,nod z){ nod X=(nod){x.x-y.x,x.y-y.y},Y=(nod){z.x-y.x,z.y-y.y}; return cj(X,Y)<=0; } int main(){ scanf("%d",&n); fo(i,1,n){ scanf("%d%d",&b[i].x,&b[i].y); b[i].i=i;ans[i]=-1; } scanf("%d",&k); stable_sort(b+1,b+n+1,cmp); bool go=0; fo(i,1,n){ if(b[i].i==k){ st[ss=1]=i; ans[k]=0; go=1; continue; } if(!go)continue; if(cj(b[st[1]],b[i])==0)continue; for(;ss>1&&pd(b[st[ss-1]],b[st[ss]],b[i]);)--ss; st[++ss]=i; ans[b[i].i]=p[ss]=p[ss-1]+cj(b[st[ss-1]],b[st[ss]]); } fo(i,1,n)printf("%lld\n",ans[i]); }