题目链接:
http://codeforces.com/problemset/problem/704/B
题目大意:
给N个点,起点S终点T,每个点有X,A,B,C,D,根据I和J的X坐标可得I到J的距离计算公式:(题目描述的那个i<j有错!害我WA了好几次)
- |xi - xj| + ci + bj seconds if x[j] < x[i].
- |xi - xj| + di + aj seconds otherwise (x[j] > x[i]).
求从起点到终点,经过N个点恰好一次的最短路。
题目思路:
【贪心】
这题首先一看过去觉得像DP题,但是数据好大,一时不知道怎么做。
我是先把每个点到其他点的距离算出来,然后一个一个往S到T中间插入点,用一个链表记录每个点到达的下一个点。
如果把当前结点I插在J和K中间比插在其他区间更优就更新答案。
1 // 2 //by coolxxx 3 //#include<bits/stdc++.h> 4 #include<iostream> 5 #include<algorithm> 6 #include<string> 7 #include<iomanip> 8 #include<map> 9 #include<memory.h> 10 #include<time.h> 11 #include<stdio.h> 12 #include<stdlib.h> 13 #include<string.h> 14 //#include<stdbool.h> 15 #include<math.h> 16 #define min(a,b) ((a)<(b)?(a):(b)) 17 #define max(a,b) ((a)>(b)?(a):(b)) 18 #define abs(a) ((a)>0?(a):(-(a))) 19 #define lowbit(a) (a&(-a)) 20 #define sqr(a) ((a)*(a)) 21 #define swap(a,b) ((a)^=(b),(b)^=(a),(a)^=(b)) 22 #define mem(a,b) memset(a,b,sizeof(a)) 23 #define eps (1e-8) 24 #define J 10 25 #define mod 1000000007 26 #define MAX 0x7f7f7f7f 27 #define PI 3.14159265358979323 28 #define N 5004 29 using namespace std; 30 typedef long long LL; 31 int cas,cass; 32 int n,m,lll,ans; 33 double anss; 34 int pre[N],next[N]; 35 LL aans,sum; 36 LL x[N],a[N],b[N],c[N],d[N]; 37 LL dis[N][N]; 38 int main() 39 { 40 #ifndef ONLINE_JUDGE 41 // freopen("1.txt","r",stdin); 42 // freopen("2.txt","w",stdout); 43 #endif 44 int i,j,k; 45 int s,t,mark; 46 // for(scanf("%d",&cas);cas;cas--) 47 // for(scanf("%d",&cas),cass=1;cass<=cas;cass++) 48 // while(~scanf("%s",s+1)) 49 while(~scanf("%d",&n)) 50 { 51 scanf("%d%d",&s,&t); 52 for(i=1;i<=n;i++)scanf("%I64d",&x[i]); 53 for(i=1;i<=n;i++)scanf("%I64d",&a[i]); 54 for(i=1;i<=n;i++)scanf("%I64d",&b[i]); 55 for(i=1;i<=n;i++)scanf("%I64d",&c[i]); 56 for(i=1;i<=n;i++)scanf("%I64d",&d[i]); 57 for(i=1;i<=n;i++) 58 { 59 for(j=1;j<=n;j++) 60 { 61 if(i==j)continue; 62 if(x[j]<x[i])dis[i][j]=abs(x[i]-x[j])+c[i]+b[j]; 63 else dis[i][j]=abs(x[i]-x[j])+d[i]+a[j]; 64 } 65 } 66 aans=dis[s][t]; 67 next[s]=t; 68 for(i=1;i<=n;i++) 69 { 70 if(i==s ||i==t)continue; 71 for(j=s,sum=1e18;j!=t;j=next[j]) 72 { 73 k=next[j]; 74 if(dis[j][i]+dis[i][k]-dis[j][k]<sum)sum=dis[j][i]+dis[i][k]-dis[j][k],mark=j; 75 } 76 aans+=sum; 77 j=mark;k=next[j]; 78 next[j]=i; 79 next[i]=k; 80 } 81 printf("%I64d\n",aans); 82 } 83 return 0; 84 } 85 /* 86 // 87 88 // 89 */
来源:https://www.cnblogs.com/Coolxxx/p/5794100.html