解题:SCOI 2007 蜥蜴
Posted ydnhaha
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了解题:SCOI 2007 蜥蜴相关的知识,希望对你有一定的参考价值。
拆点跑最大流
所有能跑出去的点连向汇点,容量为inf
原点连向所有初始有蜥蜴的点,容量为1
每根柱子拆成两个点“入口”和“出口”,入口向出口连容量为高度的边,出口向别的有高度的柱子的入口连容量为高度的边
1 #include<cmath> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 const int N=1000,M=100000,inf=1e9; 7 int n,m,d,f,b,s,t,t1,t2,t3,cnt,tot,ans; 8 int p[N],pp[N],dep[N],que[N],idx[N][N]; 9 int noww[M],goal[M],flow[M]; 10 char mapp[N][N]; 11 void Link(int f,int t,int v) 12 { 13 noww[++cnt]=p[f],p[f]=cnt; 14 goal[cnt]=t,flow[cnt]=v; 15 noww[++cnt]=p[t],p[t]=cnt; 16 goal[cnt]=f,flow[cnt]=0; 17 } 18 int Dis(int a,int b,int c,int d) 19 { 20 return (a-c)*(a-c)+(b-d)*(b-d); 21 } 22 void Init(int st,int ed) 23 { 24 for(int i=1;i<=ed;i++) 25 pp[i]=p[i],dep[i]=-1; 26 dep[st]=0,que[f=b=0]=st; 27 } 28 bool Layering(int st,int ed) 29 { 30 Init(st,ed); 31 while(f<=b) 32 { 33 int tn=que[f++]; 34 for(int i=pp[tn];i;i=noww[i]) 35 if(dep[goal[i]]==-1&&flow[i]) 36 dep[goal[i]]=dep[tn]+1,que[++b]=goal[i]; 37 } 38 return ~dep[ed]; 39 } 40 int Augmenting(int nd,int ed,int mn) 41 { 42 if(nd==ed||!mn) return mn; 43 int tmp=0,tep=0; 44 for(int i=pp[nd];i;i=noww[i]) 45 { 46 pp[nd]=i; 47 if(dep[goal[i]]==dep[nd]+1) 48 if(tep=Augmenting(goal[i],ed,min(mn,flow[i]))) 49 { 50 flow[i]-=tep,mn-=tep; 51 flow[i^1]+=tep,tmp+=tep; 52 if(!mn) break; 53 } 54 } 55 return tmp; 56 } 57 int Dinic_Maxflow(int st,int ed) 58 { 59 int ret=0; 60 while(Layering(st,ed)) 61 ret+=Augmenting(st,ed,inf); 62 return ret; 63 } 64 int main () 65 { 66 scanf("%d%d%d",&n,&m,&d); 67 s=2*n*m+1,t=s+1,cnt=1; 68 for(int i=1;i<=n;i++) 69 { 70 scanf("%s",mapp[i]+1); 71 for(int j=1;j<=m;j++) 72 idx[i][j]=++tot; 73 } 74 for(int i=1;i<=n;i++) 75 for(int j=1;j<=m;j++) 76 if(mapp[i][j]!=‘0‘) 77 { 78 Link(idx[i][j],idx[i][j]+n*m,mapp[i][j]-‘0‘); 79 if(i-d<1||i+d>n||j-d<1||j+d>m) 80 Link(idx[i][j]+n*m,t,inf); 81 else 82 for(int k=1;k<=n;k++) 83 for(int h=1;h<=m;h++) 84 if(Dis(i,j,k,h)<=d*d&&(i!=k||j!=h)&&mapp[k][h]!=‘0‘) 85 Link(idx[i][j]+n*m,idx[k][h],mapp[i][j]-‘0‘); 86 } 87 for(int i=1;i<=n;i++) 88 { 89 scanf("%s",mapp[i]+1); 90 for(int j=1;j<=m;j++) 91 if(mapp[i][j]==‘L‘) ans++,Link(s,idx[i][j],1); 92 } 93 printf("%d ",ans-Dinic_Maxflow(s,t)); 94 return 0; 95 }
以上是关于解题:SCOI 2007 蜥蜴的主要内容,如果未能解决你的问题,请参考以下文章