P2472 [SCOI2007] 蜥蜴

时间:2023-03-21
本文章向大家介绍P2472 [SCOI2007] 蜥蜴,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

在一个 RC列的网格地图中有一些高度不同的石柱,第 ii 行 jj 列的石柱高度为 a[i][j]

一些石柱上站着一些蜥蜴,你的任务是让尽量多的蜥蜴逃到边界外。

每行每列中相邻石柱的距离为 1,蜥蜴的跳跃距离是 D,即蜥蜴可以跳到平面距离不超过 D 的任何一个石柱上。

石柱都不稳定,每次当蜥蜴跳跃时,所离开的石柱高度减 1(如果仍然落在地图内部,则到达的石柱高度不变)。

如果该石柱原来高度为 1,则蜥蜴离开后消失,以后其他蜥蜴不能落脚。

任何时刻不能有两只蜥蜴在同一个石柱上。问无法逃离的蜥蜴总数的最小值。

网络流建模,把点拆为2个

#include <iostream>
#include<cmath>
#include <queue>
#include <cstring>
#define IOS std::ios::sync_with_stdio(0)
using namespace std;
 const int N =1e4+100,M=7e5+100;

 const int inf =1e9;
 int a[N][N];
 
 int all=1,hd[N],go[M],w[M],nxt[M];
  
 int S,T;
 int dis[M],ans=0,now[M];
  
  
 int R,C,D;
 void add_(int x,int y,int z){
     nxt[++all]=hd[x]; hd[x]=all; go[all]=y;
     w[all]=z;
     swap(x,y);
     nxt[++all]=hd[x]; hd[x]=all; go[all]=y;
     w[all]=0;
 }
   bool bfs(){
     for(int i=0;i<N;i++) dis[i]=inf;
     queue<int> q;
     q.push(S);
     now[S]=hd[S];
     dis[S]=0;
     
     while(q.empty()==0){
         int x=q.front(); 
         q.pop();
         for(int i=hd[x];i;i=nxt[i]){
             int y=go[i];
             if(w[i]>0&&dis[y]==inf){
                 dis[y]=dis[x]+1;
                 now[y]=hd[y];
                 q.push(y);
                 if(y==T) return 1;
             }
         }
     }
     return 0;
 }
 int dfs(int x,int sum){
     if(x==T) return sum;
     int k,res=0;
     
     for(int i=now[x];i&∑i=nxt[i]){
         now[x]=i;
         int y=go[i]; 
         if(w[i]>0&&(dis[y]==dis[x]+1)){
             k=dfs(y,min(sum,w[i]));
             if(k==0) dis[y]=inf;
             w[i]-=k;
             w[i^1]+=k;
             res+=k;
             sum-=k;
         }
     }
     return res;
 }
 
 int ID(int i,int j){
 	return (i-1)*R+j ;
 }
 double Dis(int x1,int y1,int x2,int y2){
 	return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)); 
 }
 signed main(){
 	int Cnt= 0;
 	cin>>R>>C>>D;
 	char c; 
 	int i,j;
 	S=0,T=2*R*C+1;
 	for(i=1;i<=R;i++)
 	 for(j=1;j<=C;j++){
 	 	cin>>c;
 	 	a[i][j] =c-'0';
 	 }
 	for(i=1;i<=R;i++)
 	 for(j=1;j<=C;j++){
 	 	cin>>c;
 	 	if(c=='L'){
 	 		Cnt++;
 	 		add_(S,ID(i,j),1);
 	 	}
 	 }	
 	  for(i=1;i<=R;i++)
 	  for(j=1;j<=C;j++){
	 	   if(a[i][j])
	 	   	 add_(ID(i,j),ID(i,j)+R*C,a[i][j]) ; 	   
 	  } 
 	 
 	 for(i=1;i<=R;i++)
 	  for(j=1;j<=C;j++){
 	   if(i>D && i<=R-D && j>D && j<=C-D)
 	   		 continue ;
	 	   if(a[i][j])
	 	   	 add_(ID(i,j)+R*C,T, a[i][j]) ; 	   
 	  } 
 	  
 	 for(i=1;i<=R;i++)
 	  for(j=1;j<=C;j++)
 	   for(int k=1;k<=R;k++)
 	    for(int l=1;l<=C;l++){
 	    	if(i==k && j==l ) continue ;
 	    	if(Dis(i,j,k,l)<=double(D)&&
 	    		a[i][j]&&a[k][l])
 	    	add_(ID(i,j)+R*C,ID(k,l),inf) ;
 	    }
 	
 	int ans =0; 
 	while(bfs()) ans+=dfs(S,inf);
 	cout<< Cnt - ans<<endl;
 }

原文地址:https://www.cnblogs.com/towboa/p/17238569.html