BZOJ 1324 Exca王者之剑 最小割

题目大意:给定一个n*m的矩阵,每个格子有宝石,人任选位置出发,取走当前位置的宝石之后四周的宝石消失,然后可以走两步,重复上述过程

容易发现一个格子取了那么四周的格子都不能取 于是方格取数问题

黑白染色 黑色点连源 白色点连汇 流量为格子的权值 黑白之间连边 流量为正无穷 用总和减去最大流就是答案

以前写的EK 跑了4000+ms我也是醉了

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define M 110
#define MAX (0x7fffffff)
int m,n,sum,ans;
struct abcd{int x,y,f,next;}table[100100];int head[M][M],tot=1;
void addd(int x,int y,int tox,int toy,int f)
{
    table[++tot].x=tox;
    table[tot].y=toy;
    table[tot].f=f;
    table[tot].next=head[x][y];
    head[x][y]=tot;
}
void add(int x,int y,int tox,int toy,int f){ addd(x,y,tox,toy,f);addd(tox,toy,x,y,0); }
inline int min(int x,int y){ return x<y?x:y; }
struct que{int x,y;}q[65540];unsigned short r,h;
int f[M][M],from[M][M];
bool maxflow()
{
    int i;
    memset(f,0,sizeof f);
    q[++h].x=0;q[h].y=0;
    f[0][0]=MAX;
    while(r!=h)
    {
        r++;
        for(i=head[q[r].x][q[r].y];i;i=table[i].next)if(table[i].f)if(!f[table[i].x][table[i].y])
        {
            f[table[i].x][table[i].y]=min(f[q[r].x][q[r].y],table[i].f);
            from[table[i].x][table[i].y]=i;
            q[++h].x=table[i].x;q[h].y=table[i].y;
        }
    }
    if(!f[0][1])return 0;
    ans+=f[0][1];
    for(i=from[0][1];i;i=from[table[i^1].x][table[i^1].y])table[i].f-=f[0][1],table[i^1].f+=f[0][1];
    return 1;
}
int main()
{
    int i,j,x;
    scanf("%d%d",&m,&n);
    for(i=1;i<=m;i++)
    for(j=1;j<=n;j++)
    {
        scanf("%d",&x);
        sum+=x;
        if(i+j&1)add(i,j,0,1,x);
        else
        {
            add(0,0,i,j,x);
            if(i^1)add(i,j,i-1,j,MAX);
            if(j^1)add(i,j,i,j-1,MAX);
            if(i^m)add(i,j,i+1,j,MAX);
            if(j^n)add(i,j,i,j+1,MAX);
        }
    }
    while(maxflow());
    printf("%d",sum-ans);
}
时间: 2024-10-08 17:47:43

BZOJ 1324 Exca王者之剑 最小割的相关文章

BZOJ 1324 Exca 王者之剑 最小割

题目大意:给出一个带权值的矩阵,取走一个地方的权值之后,与其相邻的格子的权值就会变成0,问最多可以取出多少权值. 思路:Amber论文里的题.建图不难,把图染色,然后一种颜色从S连边,另一种颜色向T连边.再把相邻的格子连边,之后跑最小割,用总权值减去最大流就是答案. CODE: #include <queue> #include <cstdio> #include <cstring> #include <iostream> #include <algo

BZOJ 1324 Exca 神剑 最小割

标题效果:鉴于加权值矩阵,带走一个地方的权利值之后,与其相邻的格儿童权利值变0.问多少可以取出到右值. 思维:Amber论文题目.不难建设,图着色.颜色从S连边,还有一种颜色向T连边.再把相邻的格子连边.之后跑最小割,用总权值减去最大流就是答案. CODE: #include <queue> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm>

bzoj 1497 最大获利 - 最小割

新的技术正冲击着手机通讯市场,对于各大运营商来说,这既是机遇,更是挑战.THU集团旗下的CS&T通讯公司在新一代通讯技术血战的前夜,需要做太多的准备工作,仅就站址选择一项,就需要完成前期市场研究.站址勘测.最优化等项目.在前期市场调查和站址勘测之后,公司得到了一共N个可以作为通讯信号中转站的地址,而由于这些地址的地理位置差异,在不同的地方建造通讯中转站需要投入的成本也是不一样的,所幸在前期调查之后这些都是已知数据:建立第i个通讯中转站需要的成本为Pi(1≤i≤N).另外公司调查得出了所有期望中的

[BZOJ 2127] happiness 【最小割】

题目链接:BZOJ - 2127 题目分析 首先,每个人要么学文科,要么学理科,所以可以想到是一个最小割模型. 我们就确定一个人如果和 S 相连就是学文,如果和 T 相连就是学理. 那么我们再来确定建图.首先使用最小割,就是先加上所有可能获得的权值,再减去最小割(即不能获得的权值). 如果一个人学理,就要割掉与 S 相连的边,那么就是要割掉学文的收益.于是,对于每个点,从 S 向它连边,权值为它学文的收益. 同理,对于每个点,从它向 T 连边,权值为它学理的收益. 对于两个相邻的人,他们有同时学

BZOJ 2561 最小生成树 | 网络流 最小割

链接 BZOJ 2561 题解 用Kruskal算法的思路来考虑,边(u, v, L)可能出现在最小生成树上,就是说对于所有边权小于L的边,u和v不能连通,即求最小割: 对于最大生成树的情况也一样.容易看出两个子问题是各自独立的,把两个最小割相加即可. #include <cstdio> #include <cmath> #include <cstring> #include <algorithm> #include <queue> using

bzoj 1797: [Ahoi2009]Mincut 最小割

求最小割的可行边与必须边,先求一遍最大流,然后在残量网络上求强连通分量,对于可行边 起始点与结束点要在不同的强连通分量里,对于必须边 起始点要与S在一个SCC里 结束点要与T在一个SCC里. 1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<cstdlib> 5 #include<cmath> 6 #include<queue> 7 #incl

bzoj 4439: [Swerc2015]Landscaping -- 最小割

4439: [Swerc2015]Landscaping Time Limit: 2 Sec  Memory Limit: 512 MB Description FJ有一块N*M的矩形田地,有两种地形高地(用‘#’表示)和低地(用‘.’表示) FJ需要对每一行田地从左到右完整开收割机走到头,再对每一列从上到下完整走到头,如下图所示 对于一个4*4的田地,FJ需要走8次. 收割机是要油的,每次从高地到低地或从低地到高地需要支付A的费用. 但是FJ有黑科技,可以高地与低地的互变,都只需要一个支付B的

BZOJ 1391: [Ceoi2008]order [最小割]

1391: [Ceoi2008]order Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 1509  Solved: 460[Submit][Status][Discuss] Description 有N个工作,M种机器,每种机器你可以租或者买过来. 每个工作包括若干道工序,每道工序需要某种机器来完成,你可以通过购买或租用机器来完成. 现在给出这些参数,求最大利润 Input 第一行给出 N,M(1<=N<=1200,1<=M<=12

【COGS 2051】王者之剑 最小割

这个其实就是在说明相邻的点不能取,我们发现只要其满足这个条件他总能走出来,那么我们就最小割就是了,我们先黑白染色,S 一排黑点 一排白点 T 对于相邻的点我们就直接中间连INF,于是就满足只要一个点选了,另一个点就不能选,我们跑完最小割就得到了满足相邻的点要么都选要么只选一方的最下舍弃. #include <cstdio> #include <cstring> #define r register #define Inf 0x7f7f7f7f using namespace std