乱搞/分治最短路线段树Day 10.24
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了乱搞/分治最短路线段树Day 10.24相关的知识,希望对你有一定的参考价值。
1、斜率
可以证明如果两点之间还有一点的话那么原来的两个点连线一定不会是最大斜率
然后我就写了个沙茶分治…………
其实根据上面的推论只用枚举相邻的两个点,扫一遍就可以了
1 #include <cstdio> 2 #include <algorithm> 3 #include <iostream> 4 using namespace std; 5 typedef pair<int,int> P; 6 int n,a,b; 7 P p[500001]; 8 double ans; 9 void solve(int l,int r) 10 { 11 if (l>=r) return; 12 int mid=(l+r)/2; 13 for (int i=l;i<=r;i++) if (i!=mid) 14 { 15 ans=max(ans,double(p[mid].second-p[i].second)/(p[mid].first-p[i].first)); 16 } 17 solve(l,mid-1);solve(mid+1,r); 18 } 19 int main() 20 { 21 freopen("slope.in","r",stdin); 22 freopen("slope.out","w",stdout); 23 scanf("%d",&n); 24 for (int i=1;i<=n;i++) 25 { 26 scanf("%d%d",&a,&b); 27 p[i]=P(a,b); 28 } 29 sort(p+1,p+n+1); 30 ans=double(p[2].second-p[1].second)/(p[2].first-p[1].first); 31 solve(1,n); 32 printf("%.3f",ans); 33 }
2、最优路径
这不就是原来做的过路费吗……
1 #include <cstdio> 2 #include <iostream> 3 #include <queue> 4 #include <cstring> 5 #define ll long long 6 using namespace std; 7 typedef pair<int,int> P; 8 struct E{ 9 int next,to,w; 10 }e[250001]; 11 priority_queue<P,vector<P>,greater<P> > que; 12 int n,m,a,b,c,sz=0,head[501],v[501],reg[501],f[501]; 13 ll w[501][501]; 14 void insert(int a,int b,int w) 15 { 16 sz++; 17 e[sz].next=head[a]; 18 head[a]=sz; 19 e[sz].to=b; 20 e[sz].w=w; 21 } 22 void dijkstra(int s) 23 { 24 memset(reg,0,sizeof(reg)); 25 memset(f,0x7f,sizeof(f)); 26 f[s]=1; 27 que.push(P(0,s)); 28 while(!que.empty()) 29 { 30 int x=que.top().second;que.pop(); 31 if (reg[x]) continue; 32 reg[x]=1; 33 for (int i=head[x];i;i=e[i].next) 34 { 35 if (v[e[i].to]<=v[s]&&f[e[i].to]>max(f[x],e[i].w)) 36 { 37 f[e[i].to]=max(f[x],e[i].w); 38 que.push(P(f[e[i].to],e[i].to)); 39 } 40 } 41 } 42 for (int i=1;i<=n;i++) 43 for (int j=1;j<=n;j++) 44 if (reg[i]&®[j]) w[i][j]=min(w[i][j],(ll)max(f[i],f[j])*v[s]); 45 } 46 int main() 47 { 48 freopen("path.in","r",stdin); 49 freopen("path.out","w",stdout); 50 ios::sync_with_stdio(false); 51 memset(w,0x7f,sizeof(w)); 52 cin>>n>>m; 53 for (int i=1;i<=n;i++) cin>>v[i]; 54 for (int i=1;i<=m;i++) 55 { 56 cin>>a>>b>>c; 57 insert(a,b,c);insert(b,a,c); 58 } 59 for (int i=1;i<=n;i++) dijkstra(i); 60 for (int i=1;i<=n;i++) 61 { 62 for (int j=1;j<=n;j++) 63 { 64 if (i==j){ 65 cout<<0<<" "; 66 }else{ 67 if (w[i][j]==w[0][0]) 68 cout<<-1<<" "; 69 else 70 cout<<w[i][j]<<" "; 71 } 72 } 73 cout<<endl; 74 } 75 }
3、小G的线段树
以上是关于乱搞/分治最短路线段树Day 10.24的主要内容,如果未能解决你的问题,请参考以下文章
bzoj 4016 [FJOI2014]最短路径树问题(最短路径树+树分治)
BZOJ 4016: [FJOI2014]最短路径树问题( 最短路 + 点分治 )
HDU - 4871 Shortest-path tree (最短路径树+ 树分治)