【问题描述】
没有环的有向图称为有向无环图,这是一个多么美好的结构吖。 如果有一张有 N 个点的有向图,我们可能需要删掉一些边使它变成一张有向无环图。 假设初始时我们只有N个互不相连的点,当然它也是一张有向无环图。依次 给出 T 条边和每条边的方向。每给出一条边就要立即决定是否要加入这一条边,使得这张图始终是一张有向无环图。计算在满足要求的情况下一共有多 少条边没有被加入。如果所有边都可以加入这张图则输出0。
【输入文件】文件名:stock.in
N(1<=N<=250) T(0<=T<=500,000) T
第一行为两个整数: , 。接下来 行,每
x,y(1<=x,y<=N) x y
行两个整数 ,表示一条从 到 的单向边。
stock.out
stock.out
【输出文件】文件名:ssttoocckk..oouutt
一个整数,表示没有被加入的边数。
【样例输入】
36
12
13
31
21
12
23
【样例输出】
2
【样例说明】
1-->2,之前2-->1没有路径,不会造成环,加入
1-->3,之前3-->1没有路径,不会造成环,加入
3-->1,之前1-->3有路径,使得图有环,不加入
2-->1,之前1-->2有路径,不加入
1-->2, 之前2-->1没有路径,加入
2-->3,之前3-->2没有路径,加入
因此答案是2
bfs 60分程序:
var a,f:array[0..300,0..300] of boolean;
d:array[0..1000] of longint;
v:array[0..1000] of boolean;
n,m,t,i,j,x,y,k,sum:longint;
function find(y,x:longint):boolean;
var i,j,t,w,now:longint;
begin
t:=0; w:=1; d[1]:=x;
fillchar(v,sizeof(v),0);
f:=a; f[x,y]:=true;
while t<w do
begin
inc(t);
now:=d[t];
for i:=1 to n do
if f[now,i] then
if not v[i] then
begin inc(w); d[w]:=i; f[x,i]:=true;
if i=x then
begin
exit(true); a:=f; end; v[i]:=true; end;
{v[now]:=false;}
end;
exit(false);
end;
begin
assign(input,'stock.in'); assign(output,'stock.out');
reset(input); rewrite(output);
readln(n,t);
for i:=1 to t do
begin
readln(x,y);
if x=y then inc(sum) else
if find(y,x) then begin inc(sum); {writeln(x,' ',y);} end
else a[x,y]:=true;
end;
writeln(sum);
close(input); close(output);
end.
90分程序:
var f:array[0..250,0..250] of boolean;
a,b:array[0..250] of longint;
n,t,i,j,k,x,y,la,lb,sum:longint;
begin
assign(input,'stock.in'); assign(output,'stock.out');
reset(input); rewrite(output);
readln(n,t);
for i:=1 to t do
begin
readln(x,y);
if (x=y) or f[y,x] then inc(sum)
else
begin
la:=1; lb:=1; a[la]:=x; b[lb]:=y;
for j:=1 to n do
if f[j,x] and not f[j,y] then
begin inc(la); a[la]:=j; end;
for j:=1 to n do
if f[y,j] and not f[x,j] then
begin inc(lb); b[lb]:=j; end;
for j:=1 to la do
for k:=1 to lb do
f[a[j],b[k]]:=true;
end;
end;
writeln(sum);
close(input); close(output);
end.
最后一组数据连标程都过不了