首页 > 其他分享 >ABC274G题解

ABC274G题解

时间:2022-10-23 13:00:14浏览次数:63  
标签:used return ABC274G int 题解 flow gap dep

这是一个比较经典的网络流的建模。

首先我们可以横着和竖着给原图编两遍号,能够一次照到的编号相同。

以样例一为例:

. . .
. # .
. . .

先横着编号:

1 1 1
2 # 3
4 4 4

再竖着编号:

5 6 8
5 # 8
5 7 8

然后我们将横着的图连源点,竖着的图连汇点,横着的与竖着的之间编号相对位置对应的也要连边,即 \(1\) 连 \(5\),\(2\) 连 \(6\),\(3\) 连 \(7\),\(4\) 连 \(8\),然后直接跑一边最大流即可。

Code

点击查看代码
#include <bits/stdc++.h>
using namespace std;
const int MAXN=1e6+5;
const int INF=0x7f7f7f7f;

// char buf[1<<21],*p1=buf,*p2=buf;
// #define getchar()(p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)){ if(ch=='-') f=-1; ch=getchar(); }
    while(isdigit(ch))
        x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
    return x*f;
}

struct edge
{
    int to,nxt,flow;
}e[MAXN<<1];

int head[MAXN],cnt=1;

inline void add(int x,int y,int f)
{
    e[++cnt].to=y;
    e[cnt].flow=f;
    e[cnt].nxt=head[x];
    head[x]=cnt;
    return;
}

inline void addn(int x,int y,int f)
{
    add(x,y,f);
    add(y,x,0);
    return;
}

int dep[MAXN],gap[MAXN];
int n,m,s,t;

inline void bfs()
{
    queue<int>q;
    memset(dep,0,sizeof(dep));
    memset(gap,0,sizeof(gap));
    dep[t]=1;
    gap[1]=1;
    q.push(t);
    while(!q.empty())
    {
        int x=q.front();q.pop();
        for(int i=head[x];i;i=e[i].nxt)
        {
            int y=e[i].to;
            if(dep[y]) continue;
            q.push(y);
            dep[y]=dep[x]+1;
            gap[dep[y]]++;
        }
    }
    return;
}

int maxflow,cur[MAXN];

inline int dfs(int x,int flow)
{
    if(x==t)
    {
        maxflow+=flow;
        return flow;
    }
    int used=0;
    for(int i=cur[x];i;i=e[i].nxt)
    {
        cur[x]=i;
        int y=e[i].to,f=e[i].flow;
        if(dep[x]==dep[y]+1 && f)
        {
            int w=dfs(y,min(f,flow-used));
            e[i].flow-=w;
            e[i^1].flow+=w;
            used+=w;
            if(used==flow) return used;
        }
    }
    gap[dep[x]]--;
    if(!gap[dep[x]]) dep[s]=n*m*2+3;
    dep[x]++,gap[dep[x]]++;
    return used;
}

inline int Isap()
{
    maxflow=0;
    bfs();
    while(dep[s]<=n*m*2+1)
        memcpy(cur,head,sizeof(cur)),dfs(s,INF);
    return maxflow;
}

char c[305][305];
int id1[305][305],id2[305][305];

int main()
{
    n=read(),m=read();
    s=0,t=n*m*2+1;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            cin>>c[i][j];
    int tot=0;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        {
            if(c[i][j]=='#') continue;
            id1[i][j]=++tot;
            int k=j+1;
            while(c[i][k]=='.') id1[i][k]=tot,k++;
            j=k;
        }
    int mid=tot;
    for(int j=1;j<=m;j++)
        for(int i=1;i<=n;i++)
        {
            if(c[i][j]=='#') continue;
            id2[i][j]=++tot;
            int k=i+1;
            while(c[k][j]=='.') id2[k][j]=tot,k++;
            i=k;
        }
    for(int i=1;i<=mid;i++) addn(s,i,1);
    for(int i=mid+1;i<=tot;i++) addn(i,t,1);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            addn(id1[i][j],id2[i][j],1);
    printf("%d\n",Isap());
    return 0;
}

标签:used,return,ABC274G,int,题解,flow,gap,dep
From: https://www.cnblogs.com/yhx-error/p/16818379.html

相关文章

  • ABC274C题解
    直接扫一遍,统计即可。点击查看代码#include<bits/stdc++.h>usingnamespacestd;constintMAXN=2e5+5;//charbuf[1<<21],*p1=buf,*p2=buf;//#definegetchar(......
  • Atcoder Regular Round #151 B题 A < AP 题解
    题意:给定一个排列\(p\),求满足下列条件的\(a\)数组的数量。\(1\lea_i\lem\)。\(a\)数组的字典序小于\(\{a_{p_1},a_{p_2},\cdots,a_{p_n}\}\)。题解:由于每......
  • luogu P8585 球状精灵的传说 题解
    题目大意给定\(n\)个精灵的三维幅度\(\{r_{1,i},r_{2,i},r_{3,i}\}\),任意两个精灵若在三个幅度中有两个相同(这里可以乱序)则可以将剩下的一位相加组合起来。组合过的精......
  • 洛谷P5020题解
    原题P5020[NOIP2018提高组]货币系统思路概述题意分析给定包含一个整数\(n\)和一个正整数集合\(a\)的货币系统\((n,a)\),要求将其化简,输出最简的货币系统中的面......
  • P4679 题解
    前言题目传送门!更好的阅读体验?大力树剖!做树剖时,大家可以膜拜@liruiduan2巨佬,他可以在考场上码200行的树剖题目。思路代码有点长。可以用这份代码对拍。/*树剖......
  • P2218 题解
    前言题目传送门!更好的阅读体验?二分答案套搜索。思路答案显然具有单调性,于是可以二分答案。问题是如何实现\(\operatorname{check}(k)\)函数(\(k\)指薄膜边长)。其......
  • 洛谷P2827题解
    原题P2827[NOIP2016提高组]蚯蚓思路概述题意分析给定整数\(n,m,q,u,v,t\)和一个数列\(\{a\}\),进行\(m\)次操作如下:每次选取其中最大数\(x\)切分为\([px],x......
  • dremio 21 版本之后反射No File System scheme matches 问题解决
    实际属于一个老问题了,整理下,方便使用,主要是我们在使用反射的时候碰到的问题问题如下UnknownFormatConversionException:Conversion='Unknownformat(pdfs)conversio......
  • CodeForces-1143#C 题解
    正文♦时间复杂度:\(\mathcal{O}(n)\)思维题,不需要建树。设数组\(a\)记录每一个节点是否尊重它的父节点,数组\(b\)记录是否有节点尊重它,特别的,叶子节点必然不被尊重。......
  • [题解]如何求连续区间最大和
    给一个数列,有正有负,如何求最大的连续区间和?需要设f数组表示每个位置为结尾的最大区间和能否让f[i]等于f[i-1]+a[i]要看这样的f[i]是否大于零如果大于0,就说明它仍然可以......