UVaLive6834 Shopping

题意:一条直线上有n个点,标号从1到n,起点为0,终点为N+1,给定m个限制关系(ci,di),访问ci点前必须先访问di点,每两个点之间是单位距离,求在限制条件下,从起点到终点访问完所有的点的最短距离。

分析:画图模拟一下可知,从起点到终点的N+1这段距离是必须的,若想距离最短,必须去重。

   比如以下样例,

10 3
3 7
8 9
2 5
试模拟一下按部就班的访问,从0开始,先访问5,再访问2,->7->3->9->8>11,最后结束,因为要满足限制条件,会重走一些路,有些重走是不可避免的,比如限制条件8 9,为了先访问9再访问8,必须将8~9这一段走2遍,但是限制条件2 5和3 7则不然,不必要将2~5和3~7都重走2遍,画图显然可知,只需将2~7重走2遍就可同时满足这两个限制条件,也就是说,如果两个限制条件走过的路有交叉(可能是包含)的话,那么取并集即可。
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cstdlib>
 4 #include<cctype>
 5 #include<cmath>
 6 #include<iostream>
 7 #include<sstream>
 8 #include<iterator>
 9 #include<algorithm>
10 #include<string>
11 #include<vector>
12 #include<set>
13 #include<map>
14 #include<stack>
15 #include<deque>
16 #include<queue>
17 #include<list>
18 typedef long long ll;
19 typedef unsigned long long llu;
20 const int INT_INF = 0x3f3f3f3f;
21 const int INT_M_INF = 0x7f7f7f7f;
22 const ll LL_INF = 0x3f3f3f3f3f3f3f3f;
23 const ll LL_M_INF = 0x7f7f7f7f7f7f7f7f;
24 const int dr[] = {0, 0, -1, 1};
25 const int dc[] = {-1, 1, 0, 0};
26 const double pi = acos(-1.0);
27 const double eps = 1e-8;
28 const int MAXN = 1000 + 10;
29 const int MAXT = 20000 + 10;
30 using namespace std;
31 struct P
32 {
33     int x, y;
34     bool operator < (const P& a)const
35     {
36         return x <  a.x || (x == a.x && y < a.y);
37     }
38 };
39 int main()
40 {
41     int N, m;
42     while(scanf("%d%d", &N, &m) == 2)
43     {
44         if(m == 0)
45         {
46             printf("%d\n", N + 1);
47             continue;
48         }
49         int ans = N + 1;
50         P num[505];
51         for(int i = 0; i < m; ++i)
52             scanf("%d%d", &num[i].x, &num[i].y);
53         sort(num, num + m);
54         int s = num[0].x;
55         int e = num[0].y;
56         for(int i = 1; i < m; ++i)
57         {
58             if(num[i].x > num[i].y) continue;
59             if(num[i].x >= s && num[i].y <= e) continue;
60             else if(num[i].x >= s && num[i].x <= e && num[i].y >= e)
61                 e = num[i].y;
62             else
63             {
64                 ans += 2 * (e - s);
65                 s = num[i].x;
66                 e = num[i].y;
67             }
68         }
69         ans += 2 * (e - s);
70         printf("%d\n", ans);
71     }
72     return 0;
73 }
 
原文地址:https://www.cnblogs.com/tyty-Somnuspoppy/p/5971057.html