首页 > 代码库 > NOI2009植物大战僵尸
NOI2009植物大战僵尸
这题应该分两步来做:
1、拓扑排序,去掉无敌点
2、求最大闭合子图
需要注意几点:
1、拓扑排序时,如果(i,j)可以攻击到(x,y),那么增加(x,y)的入度,而不是(i,j)的入度
因为入度代表着要攻击它需要事先攻击几个点
2、求最大闭合子图时,用所有的正权点-最大流
3、求最大闭合子图时,如果(i,j)可以攻击到(x,y),那么连一条边(x,y)到(i,j),容量为正无穷
因为在最大闭合子图中边(x,y)到(i,j)意味着选(x,y)就必须要选(i,j),这与实际含义相符
4、s到正权点,容量为正权点的点权
负权点到t,容量为负权点的点权的绝对值
5、要做好对数据规模的估计
代码:
1 type node=record 2 go,next,c:longint; 3 end; 4 var e:array[0..500000] of node; 5 head,tail,i,n,m,j,tot,max,ans,s,t,x,y:longint; 6 w,cur,first,inp,q,h:array[0..1000] of longint; 7 can:array[0..1000] of boolean; 8 a:array[0..1000,0..1000] of longint; 9 procedure insert(x,y,z:longint); 10 begin 11 inc(tot); 12 e[tot].go:=y; 13 e[tot].c:=z; 14 e[tot].next:=first[x]; 15 first[x]:=tot; 16 inc(tot); 17 e[tot].go:=x; 18 e[tot].c:=0; 19 e[tot].next:=first[y]; 20 first[y]:=tot; 21 end; 22 function min(x,y:longint):longint; 23 begin 24 if x<y then exit(x) else exit(y); 25 end; 26 procedure init; 27 begin 28 readln(n,m); 29 fillchar(inp,sizeof(inp),0); 30 for i:=1 to n*m do 31 begin 32 read(w[i]);read(a[i,0]); 33 for j:=1 to a[i,0] do 34 begin 35 read(x,y);inc(x);inc(y); 36 a[i,j]:=(x-1)*m+y; 37 inc(inp[(x-1)*m+y]); 38 end; 39 if i mod m<>1 then 40 begin 41 inc(a[i,0]);a[i,a[i,0]]:=i-1;inc(inp[i-1]); 42 end; 43 readln; 44 end; 45 end; 46 procedure topsort; 47 begin 48 head:=0;tail:=0; 49 fillchar(q,sizeof(q),0); 50 fillchar(can,sizeof(can),false); 51 for i:=1 to n*m do 52 if inp[i]=0 then 53 begin 54 can[i]:=true;inc(tail);q[tail]:=i; 55 end; 56 while head<tail do 57 begin 58 inc(head); 59 x:=q[head]; 60 for i:=1 to a[x,0] do 61 begin 62 y:=a[x,i]; 63 dec(inp[y]); 64 if inp[y]=0 then 65 begin 66 can[y]:=true; 67 inc(tail); 68 q[tail]:=y; 69 end; 70 end; 71 end; 72 end; 73 procedure makegraph; 74 begin 75 max:=0; 76 for i:=1 to n*m do 77 if can[i] then 78 begin 79 if w[i]>0 then inc(max,w[i]); 80 for j:=1 to a[i,0] do 81 begin 82 y:=a[i,j]; 83 if can[y] then insert(y,i,maxlongint>>2); 84 end; 85 if w[i]>0 then insert(s,i,w[i]) 86 else insert(i,t,-w[i]); 87 end; 88 end; 89 function bfs:boolean; 90 var i,x,y:longint; 91 begin 92 fillchar(h,sizeof(h),0); 93 fillchar(q,sizeof(q),0); 94 head:=0;tail:=1;q[1]:=s;h[s]:=1; 95 while head<tail do 96 begin 97 inc(head); 98 x:=q[head]; 99 i:=first[x];100 while i<>0 do101 begin102 y:=e[i].go;103 if (h[y]=0) and (e[i].c<>0) then104 begin105 h[y]:=h[x]+1;106 inc(tail);107 q[tail]:=y;108 end;109 i:=e[i].next;110 end;111 end;112 exit(h[t]<>0);113 end;114 function dfs(x,f:longint):longint;115 var i,y,tmp,used:longint;116 begin117 if (x=t) or (f=0) then exit(f);118 i:=cur[x];tmp:=0;used:=0;119 while i<>0 do120 begin121 y:=e[i].go;122 if (h[y]=h[x]+1) and (e[i].c<>0) then123 begin124 tmp:=dfs(y,min(e[i].c,f-used));125 dec(e[i].c,tmp);126 inc(e[i xor 1].c,tmp);127 if e[i].c<>0 then cur[x]:=i;128 inc(used,tmp);129 if used=f then exit(f);130 end;131 i:=e[i].next;132 end;133 if used=0 then h[x]:=-1;134 exit(used);135 end;136 137 procedure dinic;138 begin139 while bfs do140 begin141 for i:=0 to n*m+1 do cur[i]:=first[i];142 inc(ans,dfs(s,maxlongint>>2));143 end;144 end;145 146 procedure main;147 begin148 tot:=1;149 s:=0;t:=n*m+1;150 topsort;151 makegraph;152 dinic;153 writeln(max-ans);154 end;155 begin156 init;157 main;158 end.159
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。