标签:case art ++ color string pac sample const size
3 1 1 1 0 1 2 0 0 2 0 1 1 1 -2 1 2 0 0 2 0 1 3 1 -2 1 2 0 0 2 0
2.000000 3.000000 4.472136
这道题还是有些挑战的,可以一眼看出是最短路,但如何处理出点对的直接路径?
考虑极角排序,我不会,就用三角函数的sin和cos代替,然后用bit维护,可以做到N2logN。
1 #include <algorithm> 2 #include <iostream> 3 #include <cstring> 4 #include <cstdio> 5 #include <cmath> 6 using namespace std; 7 const double eps=1e-10; 8 const int N=1010,M=4000010; 9 10 struct Node{int x,y,tp;}point[N],s,t,tmp; 11 struct Data{Node t;int id;double k,d;}st[N]; 12 int hsh[2*N],bit[2*N],csh,top;double G[N][N]; 13 14 double Dis(Node a,Node b){ 15 return sqrt(1.0*(a.x-b.x)*(a.x-b.x)+1.0*(a.y-b.y)*(a.y-b.y)); 16 } 17 18 double K1(Node b){return 1.0*(b.x-tmp.x)/Dis(tmp,b);} 19 double K2(Node b){return 1.0*(b.y-tmp.y)/Dis(tmp,b);} 20 21 int Rk1(int tp){return tp==4?1:tp==3?3:2;} 22 int Rk2(int tp){return tp==2?1:tp==1?3:2;} 23 24 bool cmp1(Data p,Data q){ 25 Node a=p.t,b=q.t; 26 if(fabs(p.k-q.k)>0)return q.k-p.k>=eps; 27 if(a.tp==4&&b.tp==4)return q.d-p.d>=eps; 28 if(a.tp==3&&b.tp==3)return p.d-q.d>=eps; 29 return Rk1(a.tp)<Rk1(b.tp); 30 } 31 32 bool cmp2(Data p,Data q){ 33 Node a=p.t,b=q.t; 34 if(fabs(p.k-q.k)>0)return p.k<q.k; 35 if(a.tp==2&&b.tp==2)return p.d<q.d; 36 if(a.tp==1&&b.tp==1)return p.d>q.d; 37 return Rk2(a.tp)<Rk2(b.tp); 38 } 39 int Query(int x,int y){int ret=0; 40 x=lower_bound(hsh+1,hsh+csh+1,x)-hsh-1; 41 while(x){ret-=bit[x];x-=x&(-x);} 42 y=lower_bound(hsh+1,hsh+csh+1,y)-hsh; 43 while(y){ret+=bit[y];y-=y&(-y);} 44 return ret; 45 } 46 47 void Add(int x,int d){ 48 x=lower_bound(hsh+1,hsh+csh+1,x)-hsh; 49 while(x<=csh)bit[x]+=d,x+=x&(-x); 50 } 51 52 int tot,n,ice,T; 53 void Solve1(int p){ 54 tmp=point[p];top=0; 55 for(int i=1;i<=tot;i++){ 56 Node b=point[i];if(tmp.y<=b.y)continue; 57 st[++top]=(Data){b,i,K1(b),Dis(tmp,b)}; 58 }sort(st+1,st+top+1,cmp1); 59 memset(bit,0,sizeof(bit)); 60 for(int i=1;i<=top;i++){ 61 Data b=st[i];Node c=b.t; 62 if(c.tp==4)Add(c.y,-1); 63 G[b.id][p]+=ice*Query(c.y,tmp.y); 64 G[p][b.id]+=ice*Query(c.y,tmp.y); 65 if(c.tp==3)Add(c.y,1); 66 } 67 } 68 69 void Solve2(int p){ 70 tmp=point[p];top=0; 71 for(int i=1;i<=tot;i++){ 72 Node b=point[i];if(tmp.x<=b.x)continue; 73 st[++top]=(Data){b,i,K2(b),Dis(tmp,b)}; 74 }sort(st+1,st+top+1,cmp2); 75 memset(bit,0,sizeof(bit)); 76 for(int i=1;i<=top;i++){ 77 Data b=st[i];Node c=b.t; 78 if(c.tp==2)Add(c.x,-1); 79 G[b.id][p]+=ice*Query(c.x,tmp.x); 80 G[p][b.id]+=ice*Query(c.x,tmp.x); 81 if(c.tp==1)Add(c.x,1); 82 } 83 } 84 85 int vis[N];double dis[N]; 86 double Dij(int s,int t){ 87 for(int i=0;i<N;i++) 88 dis[i]=1e20,vis[i]=0;dis[s]=0; 89 for(int i=1,p;i<=tot;i++){p=0; 90 for(int j=1;j<=tot;j++) 91 if(!vis[j]&&dis[p]>dis[j])p=j; 92 vis[p]=true; 93 for(int j=1;j<=tot;j++) 94 dis[j]=min(dis[j],dis[p]+G[p][j]); 95 } 96 return dis[t]; 97 } 98 99 void Initial(){ 100 memset(G,0,sizeof(G)); 101 tot=csh=0; 102 } 103 104 int main(){ 105 scanf("%d",&T); 106 while(T--){ 107 scanf("%d%d",&n,&ice);Initial(); 108 for(int i=1,x1,y1,x2,y2;i<=n;i++){ 109 scanf("%d%d%d%d",&x1,&y1,&x2,&y2); 110 hsh[++csh]=x1;hsh[++csh]=x2; 111 hsh[++csh]=y1;hsh[++csh]=y2; 112 if(x1==x2&&y1==y2)continue; 113 if(x1==x2){ 114 if(y1>y2)swap(y1,y2); 115 point[++tot]=(Node){x1,y1,1}; 116 point[++tot]=(Node){x2,y2,2}; 117 } 118 if(y1==y2){ 119 if(x1>x2)swap(x1,x2); 120 point[++tot]=(Node){x1,y1,3}; 121 point[++tot]=(Node){x2,y2,4}; 122 } 123 } 124 125 scanf("%d%d",&s.x,&s.y); 126 scanf("%d%d",&t.x,&t.y); 127 128 hsh[++csh]=s.x;hsh[++csh]=s.y; 129 hsh[++csh]=t.x;hsh[++csh]=t.y; 130 131 sort(hsh+1,hsh+csh+1); 132 csh=unique(hsh+1,hsh+csh+1)-hsh-1; 133 134 point[++tot]=(Node){s.x,s.y,0}; 135 point[++tot]=(Node){t.x,t.y,0}; 136 137 for(int i=1;i<=tot;i++)Solve1(i); 138 for(int i=1;i<=tot;i++)Solve2(i); 139 140 for(int i=1;i<=tot;i++) 141 for(int j=1;j<=tot;j++) 142 G[i][j]+=Dis(point[i],point[j]); 143 printf("%.6lf\n",Dij(tot-1,tot)); 144 } 145 return 0; 146 }
WA在求dis的平方上了,注意会爆int。
附上数据生成器:
1 #include <algorithm> 2 #include <iostream> 3 #include <cstring> 4 #include <cstdio> 5 #include <cstdlib> 6 #include <ctime> 7 using namespace std; 8 int G[1010][1010],h[1010]; 9 int main(){ 10 srand(time(NULL)); 11 int T=1,n=500,w=1000; 12 printf("%d\n",T); 13 while(T--){ 14 printf("%d %d\n",n,rand()%w); 15 int x,y,a,b,l; 16 for(int i=0;i<w;i++){ 17 h[i]=rand()*rand()%100000000; 18 if(rand()%2)h[i]*=-1; 19 } 20 sort(h,h+w); 21 memset(G,0,sizeof(G)); 22 for(int i=1;i<=n;i++){ 23 while(true){ 24 x=rand()%w;y=rand()%w; 25 while(G[x][y])x=rand()%w,y=rand()%w; 26 if(rand()%2){ 27 a=x;l=0; 28 while(y+l+1<=w&&G[x][y+l]==0)l++; 29 if(l==1)continue;b=y+rand()%(l-1)+1; 30 } 31 else{ 32 b=y;l=0; 33 while(x+l+1<=w&&G[x+l][y]==0)l++; 34 if(l==1)continue;a=x+rand()%(l-1)+1; 35 } 36 for(int j=x;j<=a;j++) 37 for(int k=y;k<=b;k++) 38 G[j][k]=1; 39 printf("%d %d %d %d\n",h[x],h[y],h[a],h[b]); 40 break; 41 } 42 } 43 x=rand()%w;y=rand()%w; 44 while(G[x][y])x=rand()%w,y=rand()%w; 45 printf("%d %d\n",h[x],h[y]);G[x][y]=1; 46 x=rand()%w;y=rand()%w; 47 while(G[x][y])x=rand()%w,y=rand()%w; 48 printf("%d %d\n",h[x],h[y]); 49 } 50 return 0; 51 }
标签:case art ++ color string pac sample const size
原文地址:http://www.cnblogs.com/TenderRun/p/5991692.html