在一个r行c列的网格地图中有一些高度不同的石柱,一些石柱上站着一些蜥蜴,你的任务是让尽量多的蜥蜴逃
到边界外。 每行每列中相邻石柱的距离为1,蜥蜴的跳跃距离是d,即蜥蜴可以跳到平面距离不超过d的任何一个石
柱上。石柱都不稳定,每次当蜥蜴跳跃时,所离开的石柱高度减1(如果仍然落在地图内部,则到达的石柱高度不
变),如果该石柱原来高度为1,则蜥蜴离开后消失。以后其他蜥蜴不能落脚。任何时刻不能有两只蜥蜴在同一个
石柱上。
标签:php set oid 超级 for 整数 geo 规模 cstring
在一个r行c列的网格地图中有一些高度不同的石柱,一些石柱上站着一些蜥蜴,你的任务是让尽量多的蜥蜴逃
到边界外。 每行每列中相邻石柱的距离为1,蜥蜴的跳跃距离是d,即蜥蜴可以跳到平面距离不超过d的任何一个石
柱上。石柱都不稳定,每次当蜥蜴跳跃时,所离开的石柱高度减1(如果仍然落在地图内部,则到达的石柱高度不
变),如果该石柱原来高度为1,则蜥蜴离开后消失。以后其他蜥蜴不能落脚。任何时刻不能有两只蜥蜴在同一个
石柱上。
输入第一行为三个整数r,c,d,即地图的规模与最大跳跃距离。以下r行为石竹的初始状态,0表示没有石柱
,1~3表示石柱的初始高度。以下r行为蜥蜴位置,“L”表示蜥蜴,“.”表示没有蜥蜴。
输出仅一行,包含一个整数,即无法逃离的蜥蜴总数的最小值。
100%的数据满足:1<=r, c<=20, 1<=d<=4
难点在于如何构图,鉴于数据大小,可以暴力构图
每根柱子分为两个点,从入点跳到出点连一条边,容量为柱子高度
如果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 }
标签:php set oid 超级 for 整数 geo 规模 cstring
原文地址:https://www.cnblogs.com/InWILL/p/9383716.html