arc074F - Lotus Leaves 最小割

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/baidu_36797646/article/details/79979093

题解:

今天考试的一道题,当时只拿了70分,后面的TLE了,先来讲一下我的建图方法:
同一行相邻两个非障碍点连流量为inf的边,同一列相邻两个非障碍点连流量为inf的边,这里两次的点是不一样的,也就是说一个非障碍点被拆成了两个点,然后代表同一个非障碍点的两个点间连流量为1的边(以上所有连的边都是双向边),跑最小割即可,点数是2nm,边数是6nm,虽然不是最优解,但也是能过的。但是今天下午调试的时候遇到了一个以前没有遇到的问题:就是建双向边的时候,每条边的反向边的初始流量是与它自己的流量一样的,而我的inf开到了2147483647,所以流量加到负数就GG了,以后要注意啊……

代码:

#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define pa pair<int,int>
const int Maxn=310;
const int inf=0x3f3f3f3f;
int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
    return x*f;
}
int n,m,mp[Maxn][Maxn],st,ed;
int num[Maxn][Maxn],tot=0;
char s[Maxn];
struct Edge{int y,d,next;}e[Maxn*Maxn*6];
int last[Maxn*Maxn<<1],cur[Maxn*Maxn<<1],len=1;

void ins(int x,int y,int d)
{
    int t=++len;
    e[t].y=y;e[t].d=d;
    e[t].next=last[x];last[x]=t;
}
void addedge_2(int x,int y,int d){ins(x,y,d),ins(y,x,d);}
int h[Maxn*Maxn<<1];
bool bfs()
{
    memset(h,0,sizeof(h));h[st]=1;
    static queue<int>q;q.push(st);
    while(!q.empty())
    {
        int x=q.front();q.pop();
        for(int i=last[x];i;i=e[i].next)
        {
            int y=e[i].y;
            if(e[i].d>0&&!h[y])h[y]=h[x]+1,q.push(y);
        }
    }
    return h[ed];
}
int dfs(int x,int f)
{
    if(x==ed)return f;
    int s=0,t;
    for(int i=cur[x];i;i=e[i].next)
    {
        int y=e[i].y;
        if(e[i].d>0&&h[y]==h[x]+1&&s<f)
        {
            cur[x]=i;
            t=dfs(y,min(e[i].d,f-s));
            s+=t;e[i^1].d+=t;e[i].d-=t;
        }
    }
    if(!s)h[x]=0;
    return s;
}
int main()
{
    n=read(),m=read();
    int stx,sty,edx,edy;
    for(int i=1;i<=n;i++)
    {
        scanf("%s",s+1);
        for(int j=1;j<=m;j++)
        {
            if(s[j]=='S')stx=i,sty=j,mp[i][j]=1;
            else if(s[j]=='T')edx=i,edy=j,mp[i][j]=2;
            else if(s[j]=='.')mp[i][j]=3;
            else mp[i][j]=4,num[i][j]=++tot;
        }
    }
    if(stx==edx||sty==edy)return puts("-1"),0;
    st=(tot<<1)+1,ed=(tot<<1)+2;
    for(int i=1;i<=n;i++)
    {
        int t=-1;
        for(int j=1;j<=m;j++)
        if(mp[i][j]!=3)
        {
            if(t!=-1)
            {
                int t1=num[i][t],t2=num[i][j];
                if(mp[i][t]==1)t1=st;
                if(mp[i][t]==2)t1=ed;
                if(mp[i][j]==1)t2=st;
                if(mp[i][j]==2)t2=ed;
                addedge_2(t1,t2,inf);
            }
            t=j;
        }
    }
    for(int j=1;j<=m;j++)
    {
        int t=-1;
        for(int i=1;i<=n;i++)
        if(mp[i][j]!=3)
        {
            if(t!=-1)
            {
                int t1=num[t][j]+tot,t2=num[i][j]+tot;
                if(mp[t][j]==1)t1=st;
                if(mp[t][j]==2)t1=ed;
                if(mp[i][j]==1)t2=st;
                if(mp[i][j]==2)t2=ed;
                addedge_2(t1,t2,inf);
            }
            t=i;
        }
    }
    for(int i=1;i<=n;i++)
    for(int j=1;j<=m;j++)
    if(mp[i][j]==4)addedge_2(num[i][j],num[i][j]+tot,1);
    int ans=0;
    while(bfs())
    {
        memcpy(cur,last,sizeof(cur));
        ans+=dfs(st,inf);
    }
    printf("%d",ans);
}
阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页