Tyvj P1153 间谍网络
代码来自dxh,注释来自lex
1 program ty1153;
2 var
3 inv,cost,nv,v,f,stk,dfn,low,min,sml:array[1..3000]of longint;
4 g,ng:array[1..3000,1..3000]of longint;
5 map:array[1..3000,1..3000]of boolean;
6 vh,vis:array[1..3000]of boolean;{vh:入栈标志,vis:访问标志}
7 i,j,k,n,m,top,time,pts,oo,ans1,ans2:longint;
8 procedure add(a,b:longint);
9 begin
10 inc(v[a]);
11 g[a,v[a]]:=b;
12 end;
13 procedure nadd(a,b:longint); {统计新图各点的出度和入度,并为新图加边}
14 begin
15 if map[a,b] then exit;
16 inc(nv[a]); {增加a入度}
17 inc(inv[b]); {增加b出度}
18 ng[a,nv[a]]:=b; {将边加入新图}
19 map[a,b]:=true;
20 end;
21 procedure push(p:longint);
22 begin
23 inc(top);
24 stk[top]:=p;
25 vh[p]:=true;
26 end;
27 function pop:longint;
28 begin
29 pop:=stk[top];
30 vh[stk[top]]:=false;
31 dec(top);
32 end;
33 procedure dfs(p:longint);
34 var
35 i,k:longint;
36 begin
37 inc(time);
38 dfn[p]:=time;
39 low[p]:=dfn[p];
40 vis[p]:=true;
41 push(p);
42 for i:=1 to v[p] do
43 if not vis[g[p,i]] then
44 begin
45 dfs(g[p,i]);
46 if low[g[p,i]]<low[p] then
47 low[p]:=low[g[p,i]]
48 end
49 else
50 if vh[g[p,i]] then
51 if low[g[p,i]]<low[p] then
52 low[p]:=low[g[p,i]];
53 if low[p]=dfn[p] then
54 begin
55 k:=0;
56 inc(pts);
57 while k<>p do
58 begin
59 k:=pop;
60 f[k]:=pts;
61 end;
62 end;
63 end;
64 procedure merge(p:longint);
65 var
66 i:longint;
67 begin
68 if cost[p]<min[f[p]] then min[f[p]]:=cost[p]; {该点的最小代价}
69 if p<sml[f[p]] then sml[f[p]]:=p; {sml是为了解决不能控制的间谍的最小编号}
70 for i:=1 to v[p] do {缩点建边}
71 nadd(f[p],f[g[p,i]]);
72 end;
73 begin
74 readln(n);
75 readln(m);
76 fillchar(cost,sizeof(cost),$6f);
77 fillchar(min,sizeof(min),$6f);
78 for i:=1 to m do
79 begin
80 readln(j,k);
81 cost[j]:=k;
82 end;
83 readln(m);
84 for i:=1 to m do
85 begin
86 readln(j,k);
87 add(j,k);
88 end;
89 fillchar(vh,sizeof(vh),false);
90 fillchar(vis,sizeof(vis),false);
91 time:=0;
92 pts:=0;
93 for i:=1 to n do
94 if not vis[i] then
95 dfs(i);
96 for i:=1 to pts do map[i,i]:=true; {此分量与自身有路,作用见第15行}
97 fillchar(sml,sizeof(sml),$6f);
98 for i:=1 to n do merge(i);
99 fillchar(oo,sizeof(oo),$6f);
100 ans2:=oo;
101 ans1:=0;
102 for i:=1 to pts do
103 if inv[i]=0 then
104 begin
105 if min[i]<>oo then {若该点入度为零,且有间谍可收买,则加钱}
106 ans1:=ans1+min[i]
107 else
108 if sml[i]<ans2 then {若该点无间谍可收买,此分量间谍不可控,更新编号最小之不可控间谍}
109 ans2:=sml[i];
110 end;
111 if ans2=oo then
112 begin
113 writeln('YES');
114 writeln(ans1);
115 end
116 else
117 begin
118 writeln('NO');
119 writeln(ans2);
120 end;
121 end.
2 var
3 inv,cost,nv,v,f,stk,dfn,low,min,sml:array[1..3000]of longint;
4 g,ng:array[1..3000,1..3000]of longint;
5 map:array[1..3000,1..3000]of boolean;
6 vh,vis:array[1..3000]of boolean;{vh:入栈标志,vis:访问标志}
7 i,j,k,n,m,top,time,pts,oo,ans1,ans2:longint;
8 procedure add(a,b:longint);
9 begin
10 inc(v[a]);
11 g[a,v[a]]:=b;
12 end;
13 procedure nadd(a,b:longint); {统计新图各点的出度和入度,并为新图加边}
14 begin
15 if map[a,b] then exit;
16 inc(nv[a]); {增加a入度}
17 inc(inv[b]); {增加b出度}
18 ng[a,nv[a]]:=b; {将边加入新图}
19 map[a,b]:=true;
20 end;
21 procedure push(p:longint);
22 begin
23 inc(top);
24 stk[top]:=p;
25 vh[p]:=true;
26 end;
27 function pop:longint;
28 begin
29 pop:=stk[top];
30 vh[stk[top]]:=false;
31 dec(top);
32 end;
33 procedure dfs(p:longint);
34 var
35 i,k:longint;
36 begin
37 inc(time);
38 dfn[p]:=time;
39 low[p]:=dfn[p];
40 vis[p]:=true;
41 push(p);
42 for i:=1 to v[p] do
43 if not vis[g[p,i]] then
44 begin
45 dfs(g[p,i]);
46 if low[g[p,i]]<low[p] then
47 low[p]:=low[g[p,i]]
48 end
49 else
50 if vh[g[p,i]] then
51 if low[g[p,i]]<low[p] then
52 low[p]:=low[g[p,i]];
53 if low[p]=dfn[p] then
54 begin
55 k:=0;
56 inc(pts);
57 while k<>p do
58 begin
59 k:=pop;
60 f[k]:=pts;
61 end;
62 end;
63 end;
64 procedure merge(p:longint);
65 var
66 i:longint;
67 begin
68 if cost[p]<min[f[p]] then min[f[p]]:=cost[p]; {该点的最小代价}
69 if p<sml[f[p]] then sml[f[p]]:=p; {sml是为了解决不能控制的间谍的最小编号}
70 for i:=1 to v[p] do {缩点建边}
71 nadd(f[p],f[g[p,i]]);
72 end;
73 begin
74 readln(n);
75 readln(m);
76 fillchar(cost,sizeof(cost),$6f);
77 fillchar(min,sizeof(min),$6f);
78 for i:=1 to m do
79 begin
80 readln(j,k);
81 cost[j]:=k;
82 end;
83 readln(m);
84 for i:=1 to m do
85 begin
86 readln(j,k);
87 add(j,k);
88 end;
89 fillchar(vh,sizeof(vh),false);
90 fillchar(vis,sizeof(vis),false);
91 time:=0;
92 pts:=0;
93 for i:=1 to n do
94 if not vis[i] then
95 dfs(i);
96 for i:=1 to pts do map[i,i]:=true; {此分量与自身有路,作用见第15行}
97 fillchar(sml,sizeof(sml),$6f);
98 for i:=1 to n do merge(i);
99 fillchar(oo,sizeof(oo),$6f);
100 ans2:=oo;
101 ans1:=0;
102 for i:=1 to pts do
103 if inv[i]=0 then
104 begin
105 if min[i]<>oo then {若该点入度为零,且有间谍可收买,则加钱}
106 ans1:=ans1+min[i]
107 else
108 if sml[i]<ans2 then {若该点无间谍可收买,此分量间谍不可控,更新编号最小之不可控间谍}
109 ans2:=sml[i];
110 end;
111 if ans2=oo then
112 begin
113 writeln('YES');
114 writeln(ans1);
115 end
116 else
117 begin
118 writeln('NO');
119 writeln(ans2);
120 end;
121 end.
posted on 2011-03-10 21:49 Lex Luthor 阅读(440) 评论(0) 编辑 收藏 举报