题目链接:
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
