BZOJ 1066 [SCOI2007]蜥蜴
PS:变量名引起的血案。。
代名词:dinic,建图,简单网络流,点的流量限制。
step1:当点有容量时把点一分为二,cap为点的容量
step2:加入源点 汇点
step3:每个点 家一个点 我们可以这样加,mp[i][j]=++cnt;cnt++;
最后一个cnt++ 的cnt是加入的点
step4:源点到每一个石头add(s,y,1);
每个石头到一个汇点add(y`,t,inf);
然后我们还要判断该石头能否到外面。
PS:建图小心变量。
1 #include <stdio.h> 2 #include <algorithm> 3 #include <string.h> 4 #include <iostream> 5 #include <string> 6 #include <queue> 7 #include <string.h> 8 #include <cmath> 9 10 using namespace std; 11 12 #define N 200240 13 #define inf 0x3f3f3f 14 15 struct edge 16 { 17 int next,v,c; 18 }e[N<<1]; 19 20 int tot,head[N],d[N]; 21 int q[N<<2]; 22 23 int min(int a,int b) 24 { 25 return a<b?a:b; 26 } 27 28 void add(int u,int v,int c) 29 { 30 e[tot].v=v;e[tot].c=c; 31 e[tot].next=head[u];head[u]=tot++; 32 33 e[tot].v=u;e[tot].c=0; 34 e[tot].next=head[v];head[v]=tot++; 35 } 36 37 int bfs(int s,int t) 38 { 39 memset(d,-1,sizeof(d)); 40 int f=0,r=0; 41 q[r++]=s; 42 d[s]=0; 43 44 while (f<r) 45 { 46 int u=q[f++]; 47 if (u==t) return 1; 48 for (int i=head[u];i!=-1;i=e[i].next) 49 { 50 int v=e[i].v; 51 if (d[v]==-1&&e[i].c>0) 52 { 53 d[v]=d[u]+1; 54 q[r++]=v; 55 } 56 } 57 } 58 return 0; 59 } 60 61 int dfs(int s,int t,int b) 62 { 63 int r=0; 64 if (s==t) return b; 65 for (int i=head[s];i!=-1&&r<b;i=e[i].next) 66 { 67 int v=e[i].v; 68 if (e[i].c>0&&d[v]==d[s]+1) 69 { 70 int x=min(e[i].c,b-r); 71 x=dfs(v,t,x); 72 r+=x; 73 e[i].c-=x; 74 e[i^1].c+=x; 75 } 76 } 77 if (!r) d[s]-=2; 78 return r; 79 } 80 81 int dinic(int s,int t) 82 { 83 int ans=0,tmp; 84 while (bfs(s,t)) 85 { 86 while (tmp=dfs(s,t,inf)) ans+=tmp; 87 } 88 return ans; 89 } 90 void init() 91 { 92 tot=0; 93 memset(head,-1,sizeof(head)); 94 } 95 96 char s[123][123]; 97 char ss[123][123]; 98 int mp[123][123]; 99 100 int dis(int x,int y,int xx,int yy) 101 { 102 return (xx-x)*(xx-x)+(yy-y)*(yy-y); 103 } 104 105 106 int main() 107 { 108 int r,c,d; 109 int cnt=0; 110 111 scanf("%d%d%d",&r,&c,&d); 112 113 for (int i=1;i<=r;i++){ 114 scanf("%s",s[i]+1); 115 for (int j=1;j<=c;j++) 116 if (s[i][j]!='0'){ 117 mp[i][j]=++cnt; 118 cnt++; 119 } 120 } 121 122 init(); 123 124 for (int i=1;i<=r;i++) 125 scanf("%s",ss[i]+1); 126 127 int h=0,t=cnt+1; 128 129 for (int i=1;i<=r;i++) 130 for (int j=1;j<=c;j++) 131 if (s[i][j]>'0') 132 add(mp[i][j],mp[i][j]+1,s[i][j]-'0'); 133 134 int ans=0; 135 for (int i=1;i<=r;i++) 136 for (int j=1;j<=c;j++){ 137 if (ss[i][j]=='L') 138 { 139 ans++; 140 add(0,mp[i][j],1); 141 } 142 if (s[i][j]>'0') { 143 if (i<=d||(r-i)<d||j<=d||(c-j)<d) add(mp[i][j]+1,t,inf); 144 } 145 } 146 147 for (int i=1;i<=r;i++) 148 for (int j=1;j<=c;j++) 149 { 150 for (int p=1;p<=r;p++) 151 for (int k=1;k<=c;k++) 152 if (!(i==p&&j==k)) 153 { 154 if (s[i][j]>'0'&&s[p][k]>'0'&&dis(i,j,p,k)<=d*d) 155 add(mp[i][j]+1,mp[p][k],inf); 156 } 157 } 158 printf("%d\n",ans-dinic(h,t)); 159 return 0; 160 }
随性Code