添边问题(Floyd)

添边问题
(程序文件名: stock.pas/c/cpp)
【问题描述】
没有环的有向图称为有向无环图,这是一个多么美好的结构吖。
如果有一张有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
一个整数,表示没有被加入的边数。
【样例输入】
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

program df;
var i,j,n,m,x,y,z,k,t,l,r:longint;
a,b:array[0..1000,0..1000] of longint;
c,d:array[0..1000000] of longint;
begin
assign(input,’stock.in’);
reset(input);
assign(output,’stock.out’);
rewrite(output);
readln(n,m);

t:=0;
for i:=1 to m do
begin
readln(x,y);
if (a[y,x]=1) or (y=x) then //成环和自环不可添加
begin
inc(t);
continue;
end;
l:=1; r:=1;
c[1]:=x; d[1]:=y;
for j:=1 to n do
if (a[j,x]=1) and (a[j,y]=0) then //将能与x连接的边记录
begin
inc(l);
c[l]:=j;
end;
for j:=1 to n do
if (a[y,j]=1) and (a[x,j]=0) then //将y能连接的边记录
begin
inc(r);
d[r]:=j;
end;
for j:=1 to l do
for k:=1 to r do
a[c[j],d[k]]:=1; //能连接的边连接
end;
writeln(t);
close(input);
close(output);
end.

posted @ 2017-05-21 08:55  Gxyhqzt  阅读(216)  评论(0)    收藏  举报