解题报告 地震

地震(damage.pas/c/cpp)

 

【题目描述】

    农夫John的农场遭受了一场地震。有一些牛棚遭到了损坏,但幸运地,所有牛棚间的路经都还能使用。 FJ的农场有P(1 <= P <= 30,000)个牛棚,编号1..P, C(1 <= C <= 100,000)双向路经连接这些牛棚,编号为1..C。 路经i连接牛棚a_ib_i (1 <= a_i<= P;1 <= b_i <= P),路经可能连接a_i到它自己,两个牛棚之间可能有多条路经。农庄在编号为1的牛棚.,N (1 <= N <= P)头在不同牛棚的牛通过手机短信report_j(2 <= report_j <= P)告诉FJ它们的牛棚(report_j)没有损坏,但是它们无法通过路经和没有损坏的牛棚回到到农场。 当FJ接到所有短信之后,找出最小的不可能回到农庄的牛棚数目。这个数目包括损坏的牛棚。  

 

【输入格式】

1三个空格分开的数: P, C, 和 N * 2..C+1每行两个空格分开的数: a_i 和 b_i * C+2..C+N+1每行一个数: report_j 

 

【输出格式】

1一个数,最少不能回到农庄的牛的数目(包括损坏的牛棚). 

 

【输入样例】

4 3 1
    1 2
    2 3
    3 4
    3 

 

【输出样例】

 

【hint】

牛棚2遭到损坏,导致牛棚2, 3, 4里面的牛无法回到农庄.

 

 

 

贪心,首先分析,如果一个点打电话说到达不了,那么,沿 1 号点向这个点往后,所有的点都到达不了。所以,这个点连到 1 号点路径上它前面的最后一个点一定有一个是坏的(为了影响最小,贪心)。

最后遍历图,确定有哪些点不能到达。

 

代码(dsqwwe)

 

program dsqwwe;
var
sb,v:array[1..50000] of boolean;
d,first:array[1..50000] of longint;
next,t:array[1..3000000] of longint;
n,m,c,i,a,b,p,closed,open,o,x:longint;
procedure add(a,b:longint);
begin
inc(o);
t[o]:=b;
next[o]:=first[a];
first[a]:=o;
end;
begin
assign(input,'damage.in');
reset(input);
assign(output,'damage.out');
rewrite(output);

 

readln(n,m,c);
for i:=1 to m do
begin
readln(a,b);
add(a,b);
add(b,a);
end;
for i:=1 to c do
begin
readln(a);
p:=first[a];
while p<>0 do
begin
sb[t[p]]:=true;
p:=next[p];
end;
end;
if not sb[1] then
begin
closed:=1; open:=1;
d[1]:=1;
v[1]:=true;
while closed<=open do
begin
x:=d[closed];
p:=first[x];
while p<>0 do
begin
if (not v[t[p]]) and (not sb[t[p]]) then
begin
inc(open);
d[open]:=t[p];
v[t[p]]:=true;
end;
p:=next[p];
end;
inc(closed);
end;
writeln(n-open);
end
else writeln(n);
close(input);
close(output);
end.

 

 

 

posted @ 2011-11-09 18:11  木小漾  阅读(212)  评论(0编辑  收藏  举报