[题目来源]:NOIP2004
[关键字]:二分图
[题目大意]:判断是否能用两个栈将给定的序列排列成升序,如果能则输出操作序列。
//======================================================================
[分析]:易证对于i<j如果存在k,使i<j<k且a[k]<a[i]<a[j]则i和j必定不能在同一个栈里,所以将他们连一条无向边。然后就是利用染色法判断是否是一个二分图。染色时吧标号小的放进栈1就能得出字典序小的操作序列。
[代码]:
View Code
1 var
2 a, b: array[0..2000] of longint;
3 s: array[0..2000] of -1..2;
4 s1, s2: array[0..2000] of longint;
5 n, t1, t2: longint;
6
7 procedure init;
8 var
9 i: longint;
10 begin
11 readln(n);
12 for i := 1 to n do read(a[i]);
13 for i := n downto 1 do
14 begin
15 b[i] := a[i];
16 if (i < n) and (b[i] > b[i+1]) then b[i] := b[i+1];
17 s[i] := -1;
18 end;
19 //for i := 1 to n do write(b[i],'');
20 //writeln;
21 end;
22
23 procedure make(x, y: longint);
24 begin
25 if (s[x] = -1) and (s[y] <> -1) then
26 begin s[x] := 3-s[y]; exit; end;
27 if (s[x] <> -1) and (s[y] = -1) then
28 begin s[y] := 3-s[x]; exit; end;
29 if (s[x] = -1) and (s[y] = -1) then
30 begin s[x] := 1; s[y] := 2; exit; end;
31 if (s[x] <> -1) and (s[y] <> -1) then
32 if s[x] = s[y] then
33 begin
34 writeln(0);
35 halt;
36 end;
37 end;
38
39 procedure print;
40 var
41 i, r: longint;
42 begin
43 r := 1;
44 t1 := 0;
45 t2 := 0;
46 for i := 1 to n do
47 begin
48 while (s1[t1] = r) or (s2[t2] = r) do
49 begin
50 if s1[t1] = r then
51 begin
52 write('b ');
53 dec(t1);
54 inc(r);
55 end;
56 if s2[t2] = r then
57 begin
58 write('d ');
59 dec(t2);
60 inc(r);
61 end;
62 end;
63 if s[i] = 1 then
64 begin
65 write('a ');
66 inc(t1);
67 s1[t1] := a[i];
68 end;
69 if s[i] = 2 then
70 begin
71 write('c ');
72 inc(t2);
73 s2[t2] := a[i];
74 end;
75 end;
76 while (s1[t1] = r) or (s2[t2] = r) do
77 begin
78 if s1[t1] = r then
79 begin
80 write('b ');
81 dec(t1);
82 inc(r);
83 end;
84 if s2[t2] = r then
85 begin
86 write('d ');
87 dec(t2);
88 inc(r);
89 end;
90 end;
91 end;
92
93 procedure work;
94 var
95 i, j: longint;
96 begin
97 for i := 1 to n-2 do
98 for j := i+1 to n-1 do
99 if (a[i] < a[j]) and (b[j+1] < a[i]) then make(i,j);
100 for i := 1 to n do
101 if s[i] = -1 then s[i] := 1;
102 end;
103
104 begin
105 assign(input,'d:\1.in');reset(input);
106 assign(output,'d:\1.out');rewrite(output);
107 init;
108 work;
109 print;
110 close(input);
111 close(output);
112 end.