文章转载自:xuanqis.com
题目链接:点击打开链接
Description
Your friend will enjoy shopping. She will walk through a mall along a straight street, where N individual shops (numbered from 1 to N) are aligned at regular intervals. Each shop has one door and is located at the one side of the street. The distances between the doors of the adjacent shops are the same length, i.e. a unit length. Starting shopping at the entrance of the mall, she visits shops in order to purchase goods. She has to go to the exit of the mall after shopping. She requires some restrictions on visiting order of shops. Each of the restrictions indicates that she shall visit a shop before visiting another shop. For example, when she wants to buy a nice dress before choosing heels, she shall visit a boutique before visiting a shoe store. When the boutique is farther than the shoe store, she must pass the shoe store before visiting the boutique, and go back to the shoe store after visiting the boutique. If only the order of the visiting shops satisfies all the restrictions, she can visit other shops in any order she likes. Write a program to determine the minimum required walking length for her to move from the entrance to the exit. Assume that the position of the door of the shop numbered k is k units far from the entrance, where the position of the exit is N + 1 units far from the entrance.
Input
The input consists of several tests case. N m c1 d1 … cm dm For each test, the first line contains two integers N and m, where N (1 ≤ N ≤ 1000) is the number of shops, and m (0 ≤ m ≤ 500) is the number of restrictions. Each of the next m lines contains two integers ci and di (1 ≤ ci < di ≤ N) indicating the i-th restriction on the visiting order, where she must visit the shop numbered ci after she visits the shop numbered di (i = 1, . . . , m). Therearenopairofjandkthatsatisfycj =ck anddj =dk.
Output
Output the minimum required walking length for her to move from the entrance to the exit. You should omit the length of her walk in the insides of shops.
Sample Input
10 3
3 7
8 9
2 5
10 3
8 9
6 7
2 4
10 0
10 6
6 7
4 5
2 5
6 9
3 5
6 8
1000 8
3 4
6 1000
5 1000
7 1000
8 1000
4 1000
9 1000
1 2
Sample Output
23
19
11
23
2997
Hint
Source
Asia Regional Contest, Tokyo, 2014
题意
一个朋友要逛街,这条街有N个店,每个店要买些东西,但是有些店要在另外的一个店之前逛。输入店N个,m个限制,后面跟m行,每行前面的在后面的店之后逛。要求求出走的最小距离。
思路
开始以为是将所有的限制算出最大的,走到最大的走回最小的,发现不对。
其实是这样的,对于每个限制,如果小的店在大的店之前逛不用考虑,直接走;对于大的比小的先逛,就需要往回走。画一个图,将后面的先逛的限制条件所需要往回走的区间画出,将重叠的合并为一个区间,走到合并的区间的终点再往回走,这样的话原先需要走多遍的重叠的区域只需要往回走一遍,而并不需要往回走的区域就只正向走了一次。
代码
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;
struct Node{
int start;
int end;
}node[1000];
bool cmp(Node a, Node b){
return (a.start < b.start) || (a.start==b.start && a.end <= b.end);
}
int main(){
//freopen("2.txt", "r", stdin);
int N, M;
int numa, numb;
while(~scanf("%d%d", &N, &M)){ //输入总的数量和限制个数
int number = 0;
memset(node,0,sizeof(node));
for(int i=1;i<=M;i++){
scanf("%d%d", &numa, &numb);
if(numa < numb){ //只有当先走后面的再走前面的才要考虑
node[number].start=numa;
node[number++].end=numb;
}
}
sort(node,node+number,cmp); //进行排序
int left=node[0].start, right=node[0].end; //首先从第一个设置起
int label=0; //label先置为0
for(int i=1;i<number;i++){ //合并所有的节点
if(right >= node[i].start){ //存在重叠,合并
right=max(right,node[i].end); //有可能后面的起点大,终点反而比较小
node[i].start=node[i].end=0;
if(i == number-1){ //最后一个节点要特殊处理
node[label].end=right;
}
}
else{ //合并后的节点放入label,开始新一个的节点合并
node[label].end=right;
label=i;
right=node[i].end;
}
}
//node[label].end=right;
int ans=N+1;
for(int i=0;i<number;i++){
if(node[i].start != 0){ //存放了节点的节点就是要计算的
ans += 2*(node[i].end-node[i].start); //这块区域总共要走三遍,此处再算两遍
}
}
printf("%d\n", ans);
}
}