zoukankan      html  css  js  c++  java
  • [TJOI2009] 战争游戏

    题目背景

    小R正在玩一个战争游戏。游戏地图是一个M行N列的矩阵,每个格子可能是障碍物,也可能是空地,在游戏开始时有若干支敌军分散在不同的空地格子中。每支敌军都可以从当前所在的格子移动到四个相邻的格子之一,但是不能移动到包含障碍物的格子。如果敌军移动出了地图的边界,那么战争就失败了。

    题目描述

    现在你的任务是,在敌军开始移动前,通过飞机轰炸使得某些原本是空地的格子变得不可通行,这样就有可能阻止敌军移出地图边界(出于某种特殊的考虑,你不能直接轰炸敌军所在的格子)。由于地形不同的原因,把每个空地格子轰炸成不可通行所需的xx数目可能是不同的,你需要计算出要阻止敌军所需的最少的xx数。

    输入输出格式

    输入格式:

    输入文件的第一行包含两个数M和N,分别表示矩阵的长和宽。接下来M行,每行包含用空格隔开的N个数字,每个数字表示一个格子的情况:若数字为-1,表示这个格子是障碍物;若数字为0,表示这个格子里有一支敌军;若数字为一个正数x,表示这个格子是空地,且把它轰炸成不可通行所需的xx数为x。

    输出格式:

    输出一个数字,表示所需的最少xx数。数据保证有解存在。

    输入输出样例

    输入样例#1: 
    4 3
    1 2 1
    1 10 1
    1 0 -1
    1 1 1
    输出样例#1: 
    6

    说明

    对50%的数据,1 ≤ M,N ≤ 10

    对100%的数据,1 ≤ M,N ≤ 30

    矩阵里的每个数不超过100

        最小割套路题,拆点限流量,把0看成源,相邻的点之间连边,边界的点向汇连边,最小割就是答案。

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int maxn=1805;
    #define pb push_back
    const int inf=1<<30;
    vector<int> g[maxn];
    struct lines{
    	int to,flow,cap;
    }l[maxn*233];
    int S,t=-1,T,d[maxn],cur[maxn];
    bool v[maxn];
    
    inline void add(int from,int to,int cap){
    	l[++t]=(lines){to,0,cap},g[from].pb(t);
    	l[++t]=(lines){from,0,0},g[to].pb(t);
    }
    
    inline bool BFS(){
    	memset(v,0,sizeof(v));
    	queue<int> q; q.push(S);
    	v[S]=1,d[S]=0;
    	int x; lines e;
    	
    	while(!q.empty()){
    		x=q.front(),q.pop();
    		for(int i=g[x].size()-1;i>=0;i--){
    			e=l[g[x][i]];
    			if(e.flow<e.cap&&!v[e.to]) v[e.to]=1,d[e.to]=d[x]+1,q.push(e.to);
    		}
    	}
    	
    	return v[T];
    }
    
    int dfs(int x,int A){
    	if(x==T||!A) return A;
    	int flow=0,f,sz=g[x].size();
    	for(int &i=cur[x];i<sz;i++){
    		lines &e=l[g[x][i]];
    		if(d[x]+1==d[e.to]&&(f=dfs(e.to,min(A,e.cap-e.flow)))){
    			A-=f,flow+=f;
    			e.flow+=f,l[g[x][i]^1].flow-=f;
    			if(!A) break;
    		}
    	}
    	
    	return flow;
    }
    
    inline int max_flow(){
    	int an=0;
    	while(BFS()){
    		memset(cur,0,sizeof(cur));
    		an+=dfs(S,inf);
    	}
    	return an;
    }
    
    int n,m,id[233][233],cnt=0,a[233][233];
    int dx[4]={0,0,1,-1},dy[4]={1,-1,0,0};
    
    inline void build(){
    	for(int i=1;i<=n;i++)
    	    for(int j=1;j<=m;j++) if(a[i][j]>0) id[i][j]=++cnt;
    	    
    	S=0,T=cnt*2+1;
    	
    	for(int i=1;i<=n;i++)
    	    for(int j=1;j<=m;j++) if(a[i][j]>=0){
    	    	if(a[i][j]>0){
    			    add(id[i][j],id[i][j]+cnt,a[i][j]);
    	    	    if(i==1||i==n||j==1||j==m) add(id[i][j]+cnt,T,inf);
    	    	}
    	    	
    	    	for(int o=0,x,y;o<4;o++){
    	    		x=i+dx[o],y=j+dy[o];
    	    		if(x&&x<=n&&y&&y<=m&&id[x][y]) add(a[i][j]?id[i][j]+cnt:S,id[x][y],inf);
    			}
    		}
    }
    
    int main(){
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;i++)
    	    for(int j=1;j<=m;j++) scanf("%d",&a[i][j]);
    	
    	build();
    	printf("%d
    ",max_flow());
    	
    	return 0;
    }
    

      

  • 相关阅读:
    DALSA线阵相机调焦、平场校正、行频微调
    千兆网卡、万兆网卡设置
    【转载】.h头文件 .lib库文件 .dll动态库文件之间的关系,静态编译、动态编译
    【转载】工控机插槽
    镜头的选择
    相机SDK流程
    光栅尺触发DALSA线阵相机
    Go语言备忘录(3):net/http包的使用模式和源码解析
    Go语言备忘录(2):反射的原理与使用详解
    Go语言备忘录(1):基本数据结构
  • 原文地址:https://www.cnblogs.com/JYYHH/p/9073460.html
Copyright © 2011-2022 走看看