1. 程式人生 > >1066: [SCOI2007]蜥蜴

1066: [SCOI2007]蜥蜴

bool php online sof ios can com 不同的 輸入

Time Limit: 1 Sec Memory Limit: 162 MB
Submit: 4885 Solved: 2525
[Submit][Status][Discuss]

Description

  在一個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..
........
........

Sample Output

1

HINT

100%的數據滿足:1<=r, c<=20, 1<=d<=4

Source

難點在於如何構圖,鑒於數據大小,可以暴力構圖

每根柱子分為兩個點,從入點跳到出點連一條邊,容量為柱子高度

如果A柱子能跳到B柱子,那麽A柱子的出點連一條邊到B柱子入點,容量為無限INF

一個超級源與所有蜥蜴連接,容量為1

一個超級匯與所有能跳出去的柱子的出點連接,容量為無限INF

跑一遍最大流,蜥蜴數-最大流就是答案

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4
#include<algorithm> 5 #include<queue> 6 #include<cmath> 7 using namespace std; 8 9 #define sqr(x) ((x)*(x)) 10 11 const int INF=0x7fffffff; 12 13 struct data 14 { 15 int to,w,next; 16 }E[500001]; 17 int node=1,ans; 18 int head[1000],h[1000],q[1000]; 19 int r,c,d; 20 int mp[30][30],mark[30][30]; 21 22 void insert(int u,int v,int w) 23 { 24 E[++node]=(data){v,w,head[u]}; 25 head[u]=node; 26 E[++node]=(data){u,0,head[v]}; 27 head[v]=node; 28 } 29 30 bool bfs() 31 { 32 int i; 33 memset(h,-1,sizeof(h)); 34 queue<int> Q; 35 Q.push(0); 36 h[0]=0; 37 while(!Q.empty()) 38 { 39 int p=Q.front(); 40 Q.pop(); 41 i=head[p]; 42 while(i) 43 { 44 if(E[i].w&&h[E[i].to]==-1) 45 { 46 Q.push(E[i].to); 47 h[E[i].to]=h[p]+1; 48 } 49 i=E[i].next; 50 } 51 } 52 if(h[801]==-1) return 0; 53 return 1; 54 } 55 56 int dfs(int x,int f) 57 { 58 if(x==801) return f; 59 int i=head[x]; 60 int w,used=0; 61 while(i) 62 { 63 if(E[i].w&&h[E[i].to]==h[x]+1) 64 { 65 w=f-used; 66 w=dfs(E[i].to,min(w,E[i].w)); 67 E[i].w-=w; 68 E[i^1].w+=w; 69 used+=w; 70 if(used==f) return f; 71 } 72 i=E[i].next; 73 } 74 if(!used) h[x]=-1; 75 return used; 76 } 77 78 void dinic() 79 { 80 while(bfs()) ans-=dfs(0,INF); 81 } 82 83 int main() 84 { 85 scanf("%d %d %d",&r,&c,&d); 86 char ch[30]; 87 for(int i=1;i<=r;i++) 88 { 89 scanf("%s",ch+1); 90 for(int j=1;j<=c;j++) 91 mp[i][j]=ch[j]-0; 92 } 93 int tot=0; 94 for(int i=1;i<=r;i++) 95 for(int j=1;j<=c;j++) 96 mark[i][j]=++tot; 97 for(int i=1;i<=r;i++) 98 { 99 scanf("%s",ch+1); 100 for(int j=1;j<=c;j++) 101 if(ch[j]==L) 102 { 103 ans++; 104 insert(0,mark[i][j],1); 105 } 106 } 107 for(int i=1;i<=r;i++) 108 for(int j=1;j<=c;j++) 109 if(mp[i][j]) 110 { 111 insert(mark[i][j],mark[i][j]+400,mp[i][j]); 112 if(i-d<1||i+d>r||j-d<1||j+d>c) 113 insert(mark[i][j]+400,801,INF); 114 } 115 for(int x1=1;x1<=r;x1++) 116 for(int y1=1;y1<=c;y1++) 117 for(int x2=1;x2<=r;x2++) 118 for(int y2=1;y2<=c;y2++) 119 if((x1!=x2||y1!=y2)&&sqr(x1-x2)+sqr(y1-y2)<=sqr(d)&&mp[x1][y1]&&mp[x2][y2]) 120 insert(mark[x1][y1]+400,mark[x2][y2],INF); 121 dinic(); 122 printf("%d\n",ans); 123 return 0; 124 }

1066: [SCOI2007]蜥蜴