zoukankan      html  css  js  c++  java
  • bzoj4657 tower (最小割)

    4657: tower

    Time Limit: 10 Sec Memory Limit: 256 MB
    Submit: 92 Solved: 49
    [Submit][Status][Discuss]
    ## Description Nick最近在玩一款很好玩的游戏,游戏规则是这样的: 有一个n*m的地图,地图上的每一个位置要么是空地,要么是炮塔,要么是一些BETA狗,Nick需要操纵炮塔攻击BETA狗们。 攻击方法是:对于每个炮塔,游戏系统已经给出它可以瞄准的方向(上下左右其中一个),Nick需要选择它的攻击位置,每一个炮塔只能够攻击一个位置,炮塔只能够向着它的瞄准方向上的某个位置发动攻击,当然炮塔也可以不进行攻击。炮塔威力强大,它可以且仅可以消灭目标位置上所有的BETA狗。出于安全考虑,游戏系统已经保证不存在一个炮塔能够瞄准另外一个炮塔,即对于任意一个炮塔,它所有可能的攻击位置上不存在另外一个炮塔。而且,如果把炮塔的起点和终点称为炮弹的运行轨迹,那么系统不允许两条轨迹相交f包括起点和终点)。 现在,选定目标位置以后,每一个炮塔同时开炮,你要告诉Nick,他最多可以干掉多少BETA狗。 ## Input 第一行两个正整数n,m,表示地图的规模。 接下来礼行,每行m个整数,0表示空地,-1,-2,一3,-4分别表示瞄准上下左右的炮塔,若为正整数p,则表示该位置有p个BETA狗。 n,m <= 50,每个位置的BETA狗数量不超过999个,保证不存在任意一个炮塔能够瞄准另外一个炮塔 ## Output 一个正整数,表示Nick最多可以干掉几个BETA狗

    我太蠢了;
    只有横向和纵向的炮塔会冲突,所以考虑每个格子拆成两个点,横向经过和纵向经过;
    横点向纵点连流量(inf)的边,表示横纵中选一个;
    对于每个炮塔,沿着炮塔方向串成一条链;
    (S)连横向炮塔,流量(inf),横向链连边(u->v)表示选(u),流量为链上最大权值(-w[u])
    纵向炮塔连(T),流量(inf),纵向链连边(u->v)表示选(v),流量为链上最大权值(-w[v])
    答案为(Sigma)链上最大权值(-)最小割;
    AC GET☆DAZE

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<string>
    #include<cstdio>
    #include<vector>
    #include<cmath>
    #include<queue>
    #include<map>
    #include<set>
    #define N 5039
    #define mod 20070831
    #define inf 0x3f3f3f3f
    #define ll long long
    using namespace std;
    struct edge
    {
    	int to,next,cap;
    }net[N*10];
    int ans,sum,S,T,tot=-1,head[N],dis[N];
    int n,m,wa[139][139];
    void add(int u,int v,int k)
    {
    	net[++tot]=(edge){v,head[u],k},head[u]=tot;
    	net[++tot]=(edge){u,head[v],0},head[v]=tot;
    }
    bool bfs()
    {
    	memset(dis,-1,sizeof(dis));
    	queue<int> que;
    	int stp;
    	que.push(S),dis[S]=0;
    	while(!que.empty())
    	{
    		stp=que.front(),que.pop();
    		for(int a=head[stp];~a;a=net[a].next)
    		{
    			if(net[a].cap && !~dis[net[a].to])
    			{
    				dis[net[a].to]=dis[stp]+1;
    				que.push(net[a].to);
    			}
    		}
    	}
    	return dis[T]!=-1;
    }
    int dfs(int pos,int flow)
    {
    	if(pos==T || !flow) return flow;
    	int res=0,stp;
    	for(int a=head[pos];~a && flow;a=net[a].next)
    	{
    		if(net[a].cap && dis[net[a].to]==dis[pos]+1)
    		{
    			stp=dfs(net[a].to,min(flow,net[a].cap));
    			net[a].cap-=stp,net[a^1].cap+=stp;
    			flow-=stp,res+=stp;
    		}
    	}
    	if(!res) dis[pos]=-1;
    	return res;
    }
    void dinic()
    {
    	ans=0;
    	while(bfs()) ans+=dfs(S,inf);
    }
    int main()
    {
    	memset(head,-1,sizeof(head));
    	scanf("%d%d",&n,&m);
    	for(int a=1;a<=n;a++)
    	{
    		for(int b=1;b<=m;b++)
    		{
    			scanf("%d",&wa[a][b]);
    		}
    	}
    	S=0,T=n*m*2+1;
    	for(int a=1;a<=n;a++)
    	{
    		for(int b=1,c=0;b<=m;b++,c=0)
    		{
    			add((a-1)*m+b,n*m+(a-1)*m+b,inf);
    			switch(wa[a][b])
    			{
    				case -1:
    					add(S,(a-1)*m+b,inf);
    					for(int d=a-1;d;d--) if(wa[d][b]>wa[c][b]) c=d;
    					for(int d=a-1;d>c;d--) add((d-1)*m+b,(d-2)*m+b,wa[c][b]-wa[d][b]);
    					add((a-1)*m+b,(a-2)*m+b,wa[c][b]);
    					sum+=wa[c][b];
    					break;
    				case -2:
    					add(S,(a-1)*m+b,inf);
    					for(int d=a+1;d<=n;d++) if(wa[d][b]>wa[c][b]) c=d;
    					for(int d=a+1;d<c;d++) add((d-1)*m+b,d*m+b,wa[c][b]-wa[d][b]);
    					add((a-1)*m+b,a*m+b,wa[c][b]);
    					sum+=wa[c][b];
    					break;
    				case -3:
    					add(n*m+(a-1)*m+b,T,inf);
    					for(int d=b-1;d;d--) if(wa[a][d]>wa[a][c]) c=d;
    					for(int d=b-1;d>c;d--) add(n*m+(a-1)*m+d-1,n*m+(a-1)*m+d,wa[a][c]-wa[a][d]);
    					add(n*m+(a-1)*m+b-1,n*m+(a-1)*m+b,wa[a][c]);
    					sum+=wa[a][c];
    					break;
    				case -4:
    					add(n*m+(a-1)*m+b,T,inf);
    					for(int d=b+1;d<=m;d++) if(wa[a][d]>wa[a][c]) c=d;
    					for(int d=b+1;d<c;d++) add(n*m+(a-1)*m+d+1,n*m+(a-1)*m+d,wa[a][c]-wa[a][d]);
    					add(n*m+(a-1)*m+b+1,n*m+(a-1)*m+b,wa[a][c]);
    					sum+=wa[a][c];
    					break;
    			}
    		}
    	}
    	dinic();
    	printf("%d",sum-ans);
    	return 0;
    }
    
  • 相关阅读:
    使用UIImagePickerController时3DTouch引起的Crash问题的解决--备用
    阿帕奇证书配置
    终端编写c程序
    native2ascii 在 Mac终端的转码
    mac 下 配置 阿帕奇
    苹果电脑的坑
    iOS证书快要过期怎么办?
    An unspecified error occurred!
    一个苹果证书怎么多次使用
    多媒体开发之---live555的多线程支持,原本只是单线程,单通道
  • 原文地址:https://www.cnblogs.com/Sinogi/p/8659880.html
Copyright © 2011-2022 走看看