hdu
2732
每个柱子有一个高度h,代表这个柱子最多被h个蜥蜴离开,有的柱子上有一个蜥蜴,每个蜥蜴最多跳d 问最后会有多少个蜥蜴剩下。
一开始我也是没什么思路的,也是看的别人的博客,我还以为是dfs
有几个约束
1 每个柱子只能被h次离开
把每个柱子想象成点,这个点只能被h次离开也就是出度最多为h
2 有的柱子一开始就有蜥蜴
3 部分柱子可以出去
分析
一开始即源点进到柱子的流
每个柱子出去的最大流为h
但是这个柱子可能到这到那的不确定
所有再来一个与之对应的源点(出源点) 每一个柱子到其对应的出源点的最大流是h
每一个可以出去的柱子,都应该从出源点出去 没有限制 INF
每一个可以到其他地方的柱子都应该从出源点出去没有限制 INF
dinic 求最大流
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#include<string>
#include<iostream>
using namespace std;
typedef long long ll;
const ll INF=1e18;
const int maxn=1010;
const int maxm=maxn*maxn;
struct point
{
int s,e;
ll p;
};
point pp[maxn];
int temp[maxn][maxn]={0};
int map_[25][25];
int vis[25][25];
struct edge
{
int v,next;
ll w;
};
edge no[maxm];
int head[maxn];
int level[maxn];
int cnt;
queue <int> q;
bool bfs(int s,int t,int n)
{
for(int i=0;i<=n;i++)
level[i]=-1;
while(!q.empty())
{
q.pop();
}
q.push(s);
level[s]=0;
while(!q.empty())
{
int u=q.front();
if(u==t)
return true;
q.pop();
for(int i=head[u];i;i=no[i].next)
{
int v=no[i].v;
ll w=no[i].w;
if(w>0&&level[v]==-1)
{
level[v]=level[u]+1;
q.push(v);
}
}
}
return false;
}
ll dfs(int u,int t,ll max_)
{
if(u==t)
return max_;
ll sum=0;
for(int i=head[u];i;i=no[i].next)
{
edge & e=no[i];
if(e.w>0&&level[e.v]==level[u]+1)
{
ll f=dfs(e.v,t,min(max_-sum,e.w));
sum+=f;
no[i].w-=f;
no[1+((i-1)^1)].w+=f;
if(sum==max_)
break;
}
}
if(!sum)
level[u]=-1;
return sum;
}
ll dinic(int s,int t,int n)
{
ll ans=0;
while(bfs(s,t,n))
{
ll f;
while((f=dfs(s,t,INF))>0)
ans+=f;
}
return ans;
}
void init()
{
cnt=1;
for(int i=0;i<maxn;i++)
{
head[i]=0;
}
//memset(vis,0,sizeof(vis));
}
void add(int x,int y,ll w)
{
no[cnt].v=y;
no[cnt].w=w;
no[cnt].next=head[x];
head[x]=cnt;
cnt++;
}
int main()
{
int T; scanf("%d",&T);
for(int kase=1;kase<=T;kase++)
{
int s,t;
int n,m,d;
string ss;
ll xx=0;
cin>>n>>d;
init();
for(int i=1;i<=n;i++)
{
cin>>ss;
if(i==1)
{
m=ss.size();
s=0;
t=1+n*m*2;
}
for(int j=0;j<m;j++)
if(ss[j]>'0')
{
add((i-1)*m+j+1,(i-1)*m+j+1+n*m,ss[j]-'0');
add((i-1)*m+j+1+n*m,(i-1)*m+j+1,0);
if(i<=d||j+1<=d||(n-i+1)<=d||(m-j)<=d)
{
add((i-1)*m+j+1+n*m,t,INF);
add(t,(i-1)*m+j+1+n*m,0);
}
else
{
for(int k=1;k<=n;k++)
{
for(int l=0;l<m;l++)
{
if(i==k&&j==l)
continue;
if(abs(i-k)+abs(j-l)<=d)
{
add(1+j+(i-1)*m+m*n,1+l+(k-1)*m,INF);
add(1+l+(k-1)*m,1+j+(i-1)*m+m*n,0);
//add(l+(k-1)*sz,j+(i-1)*sz+sz*N,0);
}
}
}
}
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
char c;
cin>>c;
if(c=='L')
{
xx++;
add(s,j+(i-1)*m,1);
add(j+(i-1)*m,s,0);
}
}
}
ll ans = xx-dinic(s,t,2*n*m+2);
if(ans==0) printf("Case #%d: no lizard was left behind.\n",kase);
else if(ans==1) printf("Case #%d: 1 lizard was left behind.\n",kase);
else printf("Case #%d: %d lizards were left behind.\n",kase,ans);
}
return 0;
}