zoukankan      html  css  js  c++  java
  • 【BZOJ】1066: [SCOI2007]蜥蜴(最大流)

     http://www.lydsy.com/JudgeOnline/problem.php?id=1066

    本题想一想应该懂了的。

    我们想啊,,每个点都有限制,每个点都可以跳到另一个有限制的点,每个有蜥蜴的点都可以跳到四周的有限制的点,,哈哈,自然会想到网络流。

    其中很自然的可以相到,要表示每个点的容量限制,那么就拆点,一个上,一个下,容量为权值

    然后向四周连接也就是某个点的下将距离范围内的某个点的上连接,容量为oo

    源向蜥蜴连接,容量为1

    可以跑到边界外的点的下向汇连接,容量为oo

    跑一次最大流,答案就是蜥蜴总数减去最大流。

    (表示第一次做还是错了,原因在源和汇的序号啊!!!!!现在直接限定源和汇的序号,以后一定要记住!)

    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <string>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    #define rep(i, n) for(int i=0; i<(n); ++i)
    #define for1(i,a,n) for(int i=(a);i<=(n);++i)
    #define for2(i,a,n) for(int i=(a);i<(n);++i)
    #define for3(i,a,n) for(int i=(a);i>=(n);--i)
    #define for4(i,a,n) for(int i=(a);i>(n);--i)
    #define CC(i,a) memset(i,a,sizeof(i))
    #define read(a) a=getint()
    #define print(a) printf("%d", a)
    #define dbg(x) cout << #x << " = " << x << endl
    #define printarr(a, n, m) rep(aaa, n) { rep(bbb, m) cout << a[aaa][bbb]; cout << endl; }
    inline const int getint() { int r=0, k=1; char c=getchar(); for(; c<'0'||c>'9'; c=getchar()) if(c=='-') k=-1; for(; c>='0'&&c<='9'; c=getchar()) r=r*10+c-'0'; return k*r; }
    inline const int max(const int &a, const int &b) { return a>b?a:b; }
    inline const int min(const int &a, const int &b) { return a<b?a:b; }
    
    const int N=1000, M=N*4000, oo=~0u>>1;
    int ihead[N], cnt=1, cur[N], gap[N], d[N], p[N], n, m, g, a[22][22];
    struct ED { int from, to, cap, next; } e[M];
    inline const int id(const int &x, const int &y) { return (x-1)*m+y; }
    inline const bool check(const int &i, const int &j, const int &x, const int &y) { return ((i-x)*(i-x)+(j-y)*(j-y))<=g*g; }
    inline void add(const int &u, const int &v, const int &w) {
    	e[++cnt].next=ihead[u]; ihead[u]=cnt; e[cnt].to=v; e[cnt].from=u; e[cnt].cap=w;
    	e[++cnt].next=ihead[v]; ihead[v]=cnt; e[cnt].to=u; e[cnt].from=v; e[cnt].cap=0;
    }
    int isap(const int &s, const int &t, const int &n) {
    	for1(i, 0, n) cur[i]=ihead[i];
    	int ret=0, i, f, u=s;
    	gap[0]=n;
    	while(d[s]<n) {
    		for(i=cur[u]; i; i=e[i].next) if(e[i].cap && d[u]==d[e[i].to]+1) break;
    		if(i) {
    			p[e[i].to]=cur[u]=i; u=e[i].to;
    			if(u==t) {
    				for(f=oo; u!=s; u=e[p[u]].from) f=min(f, e[p[u]].cap);
    				for(u=t; u!=s; u=e[p[u]].from) e[p[u]].cap-=f, e[p[u]^1].cap+=f;
    				ret+=f;
    			}
    		}
    		else {
    			if(! (--gap[d[u]]) ) break;
    			d[u]=n; cur[u]=ihead[u];
    			for(i=ihead[u]; i; i=e[i].next) if(e[i].cap && d[u]>d[e[i].to]+1) d[u]=d[e[i].to]+1;
    			++gap[d[u]];
    			if(u!=s) u=e[p[u]].from;
    		}
    	}
    	return ret;
    }
    int main() {
    	read(n); read(m); read(g);
    	int s=900, t=901, now, tp, ans=0; char c;
    	for1(i, 1, n) for1(j, 1, m) {
    		for(c=getchar(); c<'0'||c>'9'; c=getchar());
    		tp=c-'0';
    		if(tp) {
    			now=id(i, j); a[i][j]=tp;
    			add(now, now+410, tp);
    		}
    	}
    	for1(i, 1, n) for1(j, 1, m) {
    		for(c=getchar(); c!='L'&&c!='.'; c=getchar());
    		if(c=='L') add(s, id(i, j), 1), ++ans;
    	}
    	for1(i, 1, n) for1(j, 1, m) if(a[i][j])
    		for(int x=i-g; x<=i+g; ++x) for(int y=j-g; y<=j+g; ++y)
    			if(a[x][y] && !(i==x && j==y) && check(i, j, x, y)) add(id(i, j)+410, id(x, y), oo);
    	for1(i, 1, g) for1(j, 1, m) add(id(i, j)+410, t, oo), add(id(n-i+1, j)+410, t, oo);
        for1(i, 1, g) for1(j, 1, n) add(id(j, i)+410, t, oo), add(id(j, m-i+1)+410, t, oo);
        
    	print(ans-isap(s, t, t+1));
    	return 0;
    }
    

    Description

    在一个r行c列的网格地图中有一些高度不同的石柱,一些石柱上站着 一些蜥蜴,你的任务是让尽量多的蜥蜴逃到边界外。 每行每列中相邻石柱的距离为1,蜥蜴的跳跃距离是d,即蜥蜴可以跳到平面距离不超过d的任何一个石柱上。石柱都不稳定,每次当蜥蜴跳跃时,所离开的石柱高 度减1(如果仍然落在地图内部,则到达的石柱高度不变),如果该石柱原来高度为1,则蜥蜴离开后消失。以后其他蜥蜴不能落脚。任何时刻不能有两只蜥蜴在同 一个石柱上。

    Input

    输入第一行为三个整数r,c,d,即地图的规模与最大跳跃距离。以下r行为石竹的初始状态,0表示没有石柱,1~3表示石柱的初始高度。以下r行为蜥蜴位置,“L”表示蜥蜴,“.”表示没有蜥蜴。

    Output

    输出仅一行,包含一个整数,即无法逃离的蜥蜴总数的最小值。

    Sample Input

    5 8 2
    00000000
    02000000
    00321100
    02000000
    00000000
    ........
    ........
    ..LLLL..
    ........
    ........

    Sample Output

    1

    HINT

    100%的数据满足:1<=r, c<=20, 1<=d<=3

  • 相关阅读:
    Solr4.10.2集成Nutch1.9与自带UI界面使用
    Solr4.10.2的IK Analyzer分词器配置
    Solr4.10.2的Tomcat配置
    Nutch1.9安装配置与基本使用介绍
    ubuntu14.10中tomcat8设置管理员帐号
    ubuntu14.10折腾tomcat8,是的,折腾
    spring webservice 开发demo (实现基本的CRUD 数据库采用H2)
    spring webservice 搭建出现的异常处理。异常: NAMESPACE_ERR: An attempt is made to create or change an object in a way whi
    hibernate.cfg.xml hibernate 配置文件模板
    spring 与 CXF 整合 webservice 出现error “Unable to locate Spring NamespaceHandler for XML schema namespace” 总结
  • 原文地址:https://www.cnblogs.com/iwtwiioi/p/3934172.html
Copyright © 2011-2022 走看看