HDU - 2732 -Leapin' Lizards
Posted notnight
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU - 2732 -Leapin' Lizards相关的知识,希望对你有一定的参考价值。
题目大意:一个迷宫里有n个柱子,每个柱子有一个耐久度,有些柱子上面有蜥蜴,现在发生了
火灾,这些蜥蜴想逃出去,蜥蜴每次能跳的距离为d(跳过的横纵坐标距离之和不大于d),一根柱子
每离开一只蜥蜴柱子的耐久度减1,蜥蜴跳出迷宫就算安全了,问你最少有多少个蜥蜴不能逃出去。
思路:最大流的题目,难点在于如何建边,我们可以定一个s点,然后向每个有蜥蜴的点建一条
权值为1的边,但是如果我们拿有蜥蜴的点向能到达的点建边的话,虽然我们知道当前柱子的耐久
度为u,但是我们不知道这些边的权值。 为了解决这个问题,我们可以将个点拆成两个,从原来
的点向对应的点建一条权值为u的边,然后从对应点向所能到达的点建权值为inf的边,这样能进入
对应点的话,就能到哪任何一个能到达的点。 最后我们将迷宫外面抽象为一个e点,从能到达外界
的点的对应点向e建权值为inf的边。
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=25; 4 const int inf=0x3f3f3f3f; 5 int n,m,d,id[N][N],edge[N*N*2][N*N*2],cnt,s,e,deth[N*N*2]; 6 char w[N][N],w2[N][N]; 7 int dis(int x1,int y1,int x2,int y2){ 8 return abs(x1-x2)+abs(y1-y2); 9 } 10 bool bfs(){ 11 memset(deth,0,sizeof(deth)); 12 deth[s]=1; 13 queue<int> Q; 14 Q.push(s); 15 while(!Q.empty()){ 16 int cur=Q.front(); Q.pop(); 17 if(cur==e) return true; 18 for(int i=0;i<=e;i++) 19 { 20 if(deth[i] || !edge[cur][i]) continue; 21 deth[i]=deth[cur]+1; 22 Q.push(i); 23 } 24 } 25 return false; 26 } 27 int dfs(int cur,int p){ 28 if(cur==e) return p; 29 int res=0; 30 for(int i=0;i<=e;i++){ 31 if(deth[i]!=deth[cur]+1 || !edge[cur][i]) continue; 32 int f=dfs(i,min(p-res,edge[cur][i])); 33 edge[cur][i]-=f; 34 edge[i][cur]+=f; 35 res+=f; 36 if(res==p) return res; 37 } 38 return res; 39 } 40 int Dinic(){ 41 int ans=0; 42 while(bfs()) ans+=dfs(s,inf); 43 return ans; 44 } 45 int main(){ 46 int cas; scanf("%d",&cas); 47 for(int T=1;T<=cas;T++){ 48 int res=0; 49 memset(edge,0,sizeof(edge)); cnt=0; 50 scanf("%d%d",&n,&d); 51 for(int i=1;i<=n;i++) scanf("%s",w[i]+1); 52 for(int i=1;i<=n;i++) scanf("%s",w2[i]+1); 53 m=strlen(w[1]+1); 54 for(int i=1;i<=n;i++){ 55 for(int j=1;j<=m;j++) id[i][j]=++cnt; 56 } 57 s=0;e=2*n*m+1; 58 for(int i=1;i<=n;i++){ 59 for(int j=1;j<=m;j++){ 60 if(w2[i][j]==‘L‘) edge[s][id[i][j]]+=1,res++; 61 if(w[i][j]>‘0‘ && (i-d<1 || j-d<1 || i+d>n || j+d>m)) edge[id[i][j]+n*m][e]+=inf; 62 if(w[i][j]!=‘0‘){ 63 int c=w[i][j]-‘0‘; 64 edge[id[i][j]][id[i][j]+n*m]+=c; 65 for(int u=1;u<=n;u++){ 66 for(int v=1;v<=m;v++){ 67 if(dis(i,j,u,v)<=d && w[u][v]>‘0‘ && (i!=u || j!=v)) 68 edge[id[i][j]+n*m][id[u][v]]+=inf; 69 } 70 } 71 } 72 } 73 } 74 int ans=res-Dinic(); 75 if(!ans) printf("Case #%d: no lizard was left behind.\n",T); 76 else printf("Case #%d: %d %s %s left behind.\n",T,ans,ans==1? "lizard":"lizards",ans==1? "was":"were"); 77 } 78 return 0; 79 }
ps:这题的输出真的恶心人。
以上是关于HDU - 2732 -Leapin' Lizards的主要内容,如果未能解决你的问题,请参考以下文章
BZOJ1066 [SCOI2007]蜥蜴 网络流 最大流 SAP
L - Lost's revenge HDU - 3341 (AC自动机 + 记忆化搜索 + 变进制算法)