• bzoj1001 狼抓兔子


    题目

    bzoj1001

    题解

    网络流很经典的建模,先建对偶图,再用最短路跑最小割,注意以左下为s,右上为t

    代码

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <queue>
    #define N 6001000
    #define M 2000010
    using namespace std;
     
    int n,m,s,t;
     
    int read()
    {
        int cnt=0;char ch=getchar();
        while (!isdigit(ch)) ch=getchar();
        while (isdigit(ch)) cnt=cnt*10+ch-'0',ch=getchar();
        return cnt;
    }
     
    int num,a[N],b[N],w[N],nt[N],p[M];
    void add(int x,int y,int v)
    {
        a[++num]=x;b[num]=y;w[num]=v;
        nt[num]=p[x];p[x]=num;
        a[++num]=y;b[num]=x;w[num]=v;
        nt[num]=p[y];p[y]=num;
    }
     
    int up(int x,int y) {return (x-1)*(m-1)*2+y;}
    int down(int x,int y) {return (x-1)*(m-1)*2+(m-1)+y;}
     
    void build()
    {
        s=0;t=(m-1)*(n-1)*2+1;
        for(int i=1;i<=n;i++)
            for(int j=1;j<m;j++)
            {
                int v=read();
                if(i==1) add(up(i,j),t,v);
                else if(i==n) add(s,down(i-1,j),v);
                else add(down(i-1,j),up(i,j),v);
            }   
        for(int i=1;i<n;i++)
            for(int j=1;j<=m;j++)
            {
                int v=read();
                if(j==1) add(s,down(i,j),v);
                else if(j==m) add(up(i,j-1),t,v);
                else add(up(i,j-1),down(i,j),v);
            }
        for(int i=1;i<n;i++)
            for(int j=1;j<m;j++)
            {
                int v=read();
                add(up(i,j),down(i,j),v);
            }
    }
     
    int dis[M];bool flag[M];queue<int> q;
    void spfa()
    {
        memset(dis,127,sizeof(dis));
        q.push(s);flag[s]=1;dis[s]=0;
        while(!q.empty())
        {
            int k=q.front();q.pop();
            for(int e=p[k];e;e=nt[e])
            {
                int kk=b[e];
                if(dis[kk]-dis[k]>w[e])
                {
                    dis[kk]=dis[k]+w[e];
                    if(!flag[kk]) {flag[kk]=1;q.push(kk);}
                }
            }
            flag[k]=0;
        }
    }
     
    int main() 
    {
        n=read();m=read();
        build();
        spfa();
        printf("%d",dis[t]);
        return 0;
    }
  • 相关阅读:
    linux之参数实用讲解
    Linux脚本中调用SQL,RMAN脚本
    shell for参数
    Linux Shell参数替换
    Python OOP(1)
    Python 不可变对象
    Python set
    Python tuple
    Python list,tuple,dict and set
    Python 可变长度函数参数
  • 原文地址:https://www.cnblogs.com/XYZinc/p/7388476.html
Copyright © 2020-2023  润新知