POJ 2337

POJ 2337

题目大意:多组测试数据;给出n个字符串给你, 问是否能找到一种排列方式使前一个单词的词尾与后面的单词的词头一样?

解:一开始我想错了, 把单词看成点构图bfs, 结果tle(目前构点的方式都是失败的, bfs会tle, 如果是用一些性质的话还没有yy出来)。目前的写法是用单词构边, 以26个小写英文字母为节点,问是否有一种走法使所有边都走过。这样就转化为欧拉路的问题了。然后判断是否有欧拉路或者欧拉回路(注意是在有向图上,如果所有点出度等于入度则有欧拉回路, 如果出度大于入度只大于1和入度大于出度1的有且仅有一个,说明有欧拉路,但没有回路, 无向图则是偶数边有回路, 有奇边且只有两个的话有欧拉路)。我主要错的地方有没有注意判断连通性, 没认真想问题不知道是否一次深搜即可(其实要回溯的, 如有ab, bb, ba, aba, 若果先选了ab+ba, 错了就没回头路了)

{

欧拉路径=每个点都可以到达?
一定是欧拉路径,初步结论,每个字符串设置为边!!所以一定要欧拉路(待证明)//本题中,若有a->b, b->c, c->a, c->d 的话,则一定有
题解构边,我则是构点,(貌似不行哦)试试不断删除入度为0的点(如果有多个, 说明无解, 如果没有,则挑选字典序最小即可)

}

View Code
  1 //poj 2337 of oula
2 const
3 maxm=11111;
4 type
5 data=record
6 str: string;
7 dest: char;
8 next: longint;
9 end;
10 var
11 edge: array[1..maxm]of data;
12 vect, degree: array['a'..'z']of longint;
13 a, ans: array[1..maxm]of string;
14 visit: array[1..maxm]of boolean;
15 i, total, tot, anstot, n: longint;
16 source: char;
17 flag: boolean;
18 procedure qsort(b, e: longint);
19 var
20 i, j: longint;
21 k, x: string;
22 begin
23 i := b; j := e; x := a[(i+j) >> 1];
24 repeat
25 while a[i]<x do inc(i);
26 while a[j]>x do dec(j);
27 if i<=j then begin
28 k := a[i]; a[i] := a[j]; a[j] := k;
29 inc(i); dec(j);
30 end;
31 until i>j;
32 if j>b then qsort(b, j);
33 if i<e then qsort(i, e);
34 end;
35
36 procedure add(tmp: string);
37 var
38 x, y: char;
39 begin
40 inc(tot);
41 x := tmp[1];
42 y := tmp[length(tmp)];
43 with edge[tot] do begin
44 str := tmp;
45 dest := y;
46 next := vect[x];
47 vect[x] := tot;
48 inc(degree[x]); dec(degree[y]);
49 end;
50 end;
51
52 procedure init;
53 var
54 i, j: longint;
55 x, y: char;
56 begin
57 tot := 0;
58 fillchar(vect, sizeof(vect), 0);
59 fillchar(degree, sizeof(degree), 0);
60 readln(n);
61 for i := 1 to n do readln(a[i]);
62 qsort(1, n);
63 for i := n downto 1 do add(a[i]);
64 end;
65
66 function check: boolean;
67 var
68 x, y: longint;
69 i: char;
70 begin
71 x := 0; y := 0; source := a[1][1];
72 for i := 'a' to 'z' do begin
73 if abs(degree[i])>1 then exit(false);
74 if degree[i] = 1 then source := i;
75 end;
76 exit(true);
77 end;
78
79 procedure dfs(x: char; s: longint);
80 var
81 i: longint;
82 begin
83 if s=0 then flag := true;
84 i := vect[x];
85 while i<>0 do
86 with edge[i] do begin
87 if not visit[i] then begin
88 visit[i] := true;
89 inc(anstot);
90 ans[anstot] := str;
91 dfs(dest, s-1);
92 if not flag then begin
93 dec(anstot);
94 visit[i] := false;
95 end
96 else exit;
97 end;
98 i := next;
99 end;
100 end;
101
102 procedure main;
103 begin
104 fillchar(visit, sizeof(visit), 0);
105 flag := false;
106 anstot := 0;
107 dfs(source, n);
108 end;
109
110 procedure print;
111 var
112 i: longint;
113 begin
114 if anstot <> n then begin writeln('***'); exit; end;
115 write(ans[1]);
116 for i := 2 to anstot do write('.', ans[i]);
117 writeln;
118 end;
119
120 begin
121 assign(input,'aaa.in'); reset(input);
122
123 readln(total);
124 for i := 1 to total do begin
125 init;
126 if check then main
127 else begin writeln('***'); continue; end;
128 print;
129 end;
130
131 close(input);
132 end.



原文地址:https://www.cnblogs.com/wmzisfoolish/p/2435176.html