Wikioi 3345 保存名画(拓扑排序)
3345 保存名画
时间限制: 2 s
空间限制: 256000 KB
题目等级 : 钻石 Diamond
题解
题目描述 Description
在一个Byteland上有一副非常有名的图画需要被封存。这个作品需要在2个实验室进行处理。这个处理过程被分为许多步骤。对于每个步骤,我们知道它必须要在哪个实验室进行。
在两个实验室之间运输这些这些美丽但又易碎的画会带来额外的风险,因此这个运输的过程需要尽可能的被避免。理想情况下所有的工作都会在第一个实验室做完,然后剩下的在另一个实验室完成,但是有些步骤必须在另一步骤完成之后才能完成。你的任务是找到一个工作的顺序,让这个被运输的过程最少。输出需要运输的次数。
输入描述 Input Description
第一行N和M,代表着N个步骤,和M个先后关系。下面一行N个数字,第I个数字是1或2,代表了第I个工作需要在哪个实验室完成,下面M行I,J,代表了第I个工作必须在第J个工作前完成。
你可以认为这个题目必有解
输出描述 Output Description
输出最少需要的运输次数。
样例输入 Sample Input
5 6
1 2 1 2 1
1 2
1 3
2 4
3 4
2 5
3 5
样例输出 Sample Output
2
数据范围及提示 Data Size & Hint
30%数据保证n<=5。
100%数据中n<=100000,m<=1000000。
program df;
type point=^node;
node=record
date,ends:longint;
next:point;
end;
var i,j,n,m,x,y,z,k,t,s,s1:longint; //z为起始实验室,s,s1为分别次数
path:array[0..100000] of point;
g,h:array[0..1000000] of longint;
a,c,d,f,e:array[0..100000] of longint;
b:array[0..100000] of boolean;
procedure com(x,y:longint);
var i:point;
begin
i:=path[x];
new(path[x]);
path[x]^.ends:=y;
path[x]^.next:=i;
end;
procedure dfs(x:longint);
var i:point;
y:longint;
begin
if b[x] then
inc(t);
b[x]:=false;
i:=path[x];
while i<>nil do
begin
y:=i^.ends;
dec(d[y]);
if (d[y]=0) and (a[y]=z) then dfs(y);
i:=i^.next;
end;
path[x]:=nil; //不可省(否则超时)
end;
begin
readln(n,m);
y:=0;
for i:=1 to n do
begin
read(a[i]);
if a[i]=a[i-1] then inc(y);
end;
if y=n-1 then
begin
writeln(0);
halt;
end;
for i:=1 to m do
begin
readln(g[i],h[i]);
com(g[i],h[i]);
inc(d[h[i]]);
end;
e:=d;
fillchar(b,sizeof(b),true);
t:=0; z:=1; s:=-1; //从第一实验室
while t小于n do
begin
for i:=1 to n do
if (d[i]=0) and (a[i]=z) then begin dfs(i); end;
z:=z mod 2+1; inc(s);
end;
for i:=1 to m do
com(g[i],h[i]);
d:=e;
fillchar(b,sizeof(b),true);
t:=0; z:=2; s1:=-1; //从第二实验室
while t小于n do
begin
for i:=1 to n do
if (d[i]=0) and (a[i]=z) then begin dfs(i); end;
z:=z mod 2+1; inc(s1); //记录交换的次数和交换实验室
end;
if s1>s then
writeln(s)
else writeln(s1);
end.
浙公网安备 33010602011771号