BZOJ1066 网络流
拆点,将一个柱子拆成入点和出点,入点出点之间的容量就是柱子的容量
1066: [SCOI2007]蜥蜴
在一个r行c列的网格地图中有一些高度不同的石柱,一些石柱上站着一些蜥蜴,你的任务是让尽量多的蜥蜴逃
到边界外。 每行每列中相邻石柱的距离为1,蜥蜴的跳跃距离是d,即蜥蜴可以跳到平面距离不超过d的任何一个石
柱上。石柱都不稳定,每次当蜥蜴跳跃时,所离开的石柱高度减1(如果仍然落在地图内部,则到达的石柱高度不
变),如果该石柱原来高度为1,则蜥蜴离开后消失。以后其他蜥蜴不能落脚。任何时刻不能有两只蜥蜴在同一个
石柱上。
Input
输入第一行为三个整数r,c,d,即地图的规模与最大跳跃距离。以下r行为石竹的初始状态,0表示没有石柱
,1~3表示石柱的初始高度。以下r行为蜥蜴位置,“L”表示蜥蜴,“.”表示没有蜥蜴。
Output
输出仅一行,包含一个整数,即无法逃离的蜥蜴总数的最小值。
Sample Input
5 8 2
00000000
02000000
00321100
02000000
00000000
........
........
..LLLL..
........
........
00000000
02000000
00321100
02000000
00000000
........
........
..LLLL..
........
........
Sample Output
1
1 #include<cstdio> 2 #include<queue> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 const int INF=0x3f3f3f3f; 7 int r,c,d,st,ed,tot; 8 int dis[1588],head[1588]; 9 char mp[28]; 10 struct node 11 { 12 int x,y,ab; 13 bool ri; 14 } p[588]; 15 struct line 16 { 17 int to,next,w; 18 } e[880861]; 19 void add(int u,int v,int w) 20 { 21 e[tot].to=v; 22 e[tot].next=head[u]; 23 e[tot].w=w; 24 head[u]=tot++; 25 } 26 bool bfs() 27 { 28 queue<int>Q; 29 Q.push(st); 30 memset(dis,-1,sizeof(dis)); 31 dis[st]=0; 32 while(!Q.empty()) 33 { 34 int u=Q.front(); 35 Q.pop(); 36 for(int i=head[u]; i+1; i=e[i].next) 37 { 38 int v=e[i].to; 39 if(dis[v]==-1&&e[i].w>0) 40 { 41 dis[v]=dis[u]+1; 42 if(v==ed) return true; 43 Q.push(v); 44 } 45 } 46 } 47 return false;; 48 } 49 int dfs(int u,int low) 50 { 51 if(u==ed) return low; 52 int ans=low,a; 53 for(int i=head[u]; i+1; i=e[i].next) 54 { 55 int v=e[i].to; 56 if(e[i].w>0&&dis[v]==dis[u]+1&&(a=dfs(v,min(ans,e[i].w)))) 57 { 58 e[i].w-=a; 59 e[i^1].w+=a; 60 ans-=a; 61 if(!ans) return low; 62 } 63 } 64 if(ans==low) dis[u]=-1; 65 return low-ans; 66 } 67 bool Ju(const node &A,const node &B) 68 { 69 int dis=(A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y); 70 if(dis>d) return false; 71 return true; 72 } 73 int dinic() 74 { 75 int ans=0; 76 while(bfs()) 77 { 78 ans+=dfs(0,INF); 79 } 80 return ans; 81 } 82 int main() 83 { 84 scanf("%d%d%d",&r,&c,&d); 85 int cont=0,ct=0; 86 tot=0; 87 for(int i=0; i<r; ++i) 88 { 89 scanf("%s",mp); 90 for(int j=0; j<c; ++j) 91 { 92 p[++cont].x=i; 93 p[cont].y=j; 94 p[cont].ab=mp[j]-'0'; 95 } 96 } 97 st=0,ed=2*cont+1; 98 memset(head,-1,sizeof(head)); 99 cont=0; 100 for(int i=0; i<r; ++i) 101 { 102 scanf("%s",mp); 103 for(int j=0; j<c; ++j) 104 if(mp[j]=='L') p[++cont].ri=1,++ct; 105 else p[++cont].ri=0; 106 } 107 for(int i=1; i<=cont; ++i) 108 { 109 if(p[i].ab) 110 { 111 add(i,i+cont,p[i].ab), add(i+cont,i,0); 112 if(p[i].ri) add(0,i,1),add(i,0,0); 113 for(int j=1; j<=cont; ++j) 114 { 115 if(i==j) continue; 116 if(p[j].ab&&Ju(p[i],p[j])) 117 { 118 add(i+cont,j,INF); 119 add(j,i+cont,0); 120 } 121 } 122 if(p[i].x-d<0||p[i].x+d>=r||p[i].y-d<0||p[i].y+d>=c) 123 { 124 add(i+cont,ed,INF); 125 add(ed,i+cont,0); 126 } 127 } 128 } 129 int ans=dinic(); 130 printf("%d\n",ct-ans); 131 }