欧拉回路——邮递员

题目:邮递员

描述:

邮局需要你来帮助他们为某个邮递员设计出一条能够穿过那遥远乡村的所有村子和小路至少一次的邮路(输入数据将会保证这么一条路是一定存在的)。
但是,每条路线都是有一个花费的。各个村子里的村民希望邮递员到达他们村子的时间越早越好。因此,各个村子里的人们采用了一些措施:假设第i号村子是邮递 员在他的邮递路线上到达的第k个村子。如果k<=w( i ),那么这个村子的村民就会付给邮局w( i )-k欧元。当然,如果k>w(i),邮局也同意付k- w( i )欧元给这个村子,对某些村子重复经过要重复收费。此外,邮递员每经过一条小路,邮局也要付给邮递员1欧元作为补贴。
现在有n个村子,编号依次为1到n。邮局就位于1号村子,因此邮递员的传递路线从这里开始,也从这个村子结束。能够离开每个村子的路口的数目一定是2,4或者8。这里允许出现同样的村子间存在多条小路,或者某条小路构成了一个自环的情况。
你的任务是设计一个路线使得邮局赚的钱最多(或者说赔的钱最少。如果有多种最优解,输出字典序最小的。

【输入】


第一行:两个整数n,m,分别表示村子的数量和小路的数量。
接下来n行,每行一个整数:w(i)(1≤w(i)<1000)
接下来m行,每行两个整数u,v,表示这条小路连接的村子的编号。

【输出】


第一行:一个整数k,你的程序所设计的路径的长度
第二行:k+1个整数,v1,v2…vk+l,每个数之间用一个空格隔开,表示你设计的路径所经过的村子的编号,其中需要满足v1=vk+1=1

【输入样例】


carrier.in

6 7
1
7
4
10
20
5
2 4
1 5
2 1
4 5
3 6
1 6
1 3

【输出样例】


carrier.out

7
1 2 4 5 1 3 6 1

【提示】


对于30%的数据,有N<=20
对于100%的数据,有N<=200;
补充说明:邮递员每条路线都要去送信,并且每条线路只要送一次就可以了。

解析:

      这道题只看题目描述很复杂,关键在于考虑怎样更使邮局赚钱,然后各种思路飘逸……但是,看题目评论说,欧拉回路就可以解决,真心不明白为什么这可以转化成欧拉回路的模型。但是作为一个欧拉回路的典型例题还是可以的。

AC代码:

program zht;
var
i,t,n,m,x,y,ans,tn:longint;
a:array[0..1000000] of longint;
map:array[0..200,0..200] of longint;

procedure dfs(x:longint);
var
i:longint;
begin
for i:=1 to n do
 if map[x,i]>0 then begin
 inc(ans);
 dec(map[x,i]);
 dec(map[i,x]);
 dfs(i);
 end;
 inc(tn);
 a[tn]:=x;
end;

begin
assign(input,'carrier.in');
assign(output,'carrier.out');
reset(input);
rewrite(output);

readln(n,m);

for i:=1 to n do
readln(t);

for i:=1 to m do
begin
readln(x,y);
inc(map[x,y]);
inc(map[y,x]);
end;

dfs(1);

writeln(ans);

for i:=tn downto 1 do
write(a[i],' ');

close(input);
close(output);
end.
View Code

<Marvolo原创,严禁转载>

原文地址:https://www.cnblogs.com/zhtjtcz/p/5177362.html