您的位置:首页 > 其它

[BZOJ1066]蜥蜴 做题笔记

2016-03-28 21:33 357 查看
·· / ·– ·· ·-·· ·-·· / ·–· · ·-· ··· ·· ··· - / ··- -· - ·· ·-·· / ·· / ·– ·· -·

题目来源:http://www.lydsy.com/JudgeOnline/problem.php?id=1066

做这题的时候被自己打的模板坑了,查了好久好久都没查出错。。。以后做题也不能过分信任某一段代码而不去查它的错了。

恩,这题的背景总让人想起科学的上网。。

这题的距离是指欧几里得距离,就是sqrt( (x1-x2)^2+(y1-y2)^2 ),我之前竟然没有见过,按照上下左右还有对角线去遍历,结果显而易见。。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
const int N=1000,M=100000,inf=0x3fffffff;
int head
,ver[M<<1],e[M<<1],nxt[M<<1];
int cnt=0,tot=1,frog=0,r,c,ans=0,s,t,dis;
int d
,map[100][100],pos[100][100];
void add (int u,int v,int w) {
ver[++tot]=v;e[tot]=w;nxt[tot]=head[u];head[u]=tot;
ver[++tot]=u;e[tot]=0;nxt[tot]=head[v];head[v]=tot;
}
bool bfs () {
queue <int> q;
memset(d,0,sizeof(d));
q.push(s); d[s]=1;
while (!q.empty()) {
int x=q.front(); q.pop();
for (int i=head[x];i;i=nxt[i])
if (e[i]&&!d[ver[i]]) {//这里之前打成&了
q.push(ver[i]);
d[ver[i]]=d[x]+1;
if (ver[i]==t) return 1;
}
}
return 0;
}
int dinic (int x,int f) {
int rest=f;
if (x==t) return f;
for (int i=head[x];i&&rest;i=nxt[i])
if (e[i]&&d[ver[i]]==d[x]+1) {
int now=dinic(ver[i],min(e[i],rest));
if (!now) d[ver[i]]=0;
e[i]-=now;
e[i^1]+=now;
rest-=now;
}
return f-rest;
}
bool check (int i,int j,int u,int v) {
if ( (j-v)*(j-v)+(i-u)*(i-u)<=(dis*dis)
&& map[i][j] &&map[u][v] && ((i!=u)||(j!=v))) return 1;
return 0;
}
void build () {
char ch;
cnt=r*c;s=0,t=cnt*2+1;
for (int i=1;i<=r;i++)
for (int j=1;j<=c;j++)
if (map[i][j]&&(i-1<dis ||r-i<dis ||j-1<dis ||c-j<dis ))
add(cnt+pos[i][j],t,inf);
for (int i=1;i<=r;i++)
for (int j=1;j<=c;j++)
if (map[i][j]) add(pos[i][j],cnt+pos[i][j],map[i][j]);
for (int i=1;i<=r;i++) {
for (int j=1;j<=c;j++) {
scanf("%c",&ch);
if (ch=='.') continue;
++frog;
add(s,pos[i][j],1);
}
scanf("%*c");
}
for (int i=1;i<=r;i++)
for (int j=1;j<=c;j++)
for (int u=i-dis;u<=i+dis;u++)
for (int v=j-dis;v<=j+dis;v++)
if (check(i,j,u,v)) add(cnt+pos[i][j],pos[u][v],inf);
}
int main () {
char ch;
int tmp;
scanf("%d%d%d%*c",&r,&c,&dis);
for (int i=1;i<=r;i++) {
for (int j=1;j<=c;j++) {
scanf("%c",&ch);
pos[i][j]=++cnt;
map[i][j]=ch-48;
}
scanf("%*c");
}
build();
while (bfs())
while (tmp=dinic(s,inf)) ans+=tmp;
printf("%d\n",frog-ans);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: