• [P4001 [ICPC-Beijing 2006]狼抓兔子]


    P4001 [ICPC-Beijing 2006]狼抓兔子

    题解:

    这个题目已经给你建好图了,一看就是一个最小割,但是如果真的用最小割来写,肯定会 (TLE) ,看了题解发现这个是一个 网络流最小割平面图转对偶图求最短路

    题解推荐博客:https://www.cnblogs.com/lher/p/7856451.html

    看完题解之后,就可以自己开始写了。

    注意这个每一个区域的点,是怎么定义的,因为一个格子有两个区域(也就是两个点),所以每一个格子的位置是 ((i,j)) 可以转化为数字 ((i-1)*(m-1)+j) ,因为每一个格子分成左右两个,所以继续转化,(x=((i-1)*(m-1)+j)*2) ,这样左边这个就等于 (x-1) ,右边这个区域就是 (x) ,最后就直接建图,跑最短路就可以了。

    交的时候如果用 (vector) 建图,注意开 (O2) 优化。

    #include <bits/stdc++.h>
    #define inf 0x3f3f3f3f
    #define inf64 0x3f3f3f3f3f3f3f3f
    #define debug(x) printf("debug:%s=%d
    ",#x,x);
    //#define debug(x) cout << #x << ": " << x << endl;
    using namespace std;
    typedef long long ll;
    const int maxn = 1e3+5;
    inline int read(){
        int X=0; bool flag=1; char ch=getchar();
        while(ch<'0'||ch>'9') {if(ch=='-') flag=0; ch=getchar();}
        while(ch>='0'&&ch<='9') {X=(X<<1)+(X<<3)+ch-'0'; ch=getchar();}
        if(flag) return X;
        return ~(X-1);
    }
    
    
    int row[maxn][maxn],col[maxn][maxn],a[maxn][maxn],t,n,m;
    struct node{
        int u,v,w;
        node(int u=0,int v=0,int w=0):u(u),v(v),w(w){}
    };
    struct heapnode{
        int d,u;
        heapnode(int d,int u) : d(d),u(u) {}
        bool operator<(const heapnode &a) const{
            return a.d<d;
        }
    };
    vector<node>e[2*maxn*maxn];
    void add(int u,int v,int w){
    //    printf("u=%d v=%d w=%d
    ",u,v,w);
        if(u<0||v<0) return ;
        if(u>2*(n-1)*(m-1)+1||v>2*(n-1)*(m-1)+1) return;
        e[u].push_back(node(u,v,w));
        e[v].push_back(node(v,u,w));
    }
    ll d[2*maxn*maxn];
    bool vis[2*maxn*maxn];
    priority_queue<heapnode>que;
    void dij(int s){
        while(!que.empty()) que.pop();
        for(int i=0;i<=t+10;i++) d[i]=inf64;
        d[s]=0;
        que.push(heapnode(0,s));
        while(!que.empty()){
            heapnode x=que.top();que.pop();
            int u=x.u;
            if(vis[u]) continue;
            vis[u]=1;
            for(int i=0;i<e[u].size();i++){
                node now=e[u][i];
                if(d[now.v]>d[u]+now.w){
                    d[now.v]=d[u]+now.w;
                    que.push(heapnode(d[now.v],now.v));
                }
            }
        }
    }
    
    
    int main(){
    //    scanf("%d%d",&n,&m);
        n = read(),m = read();
        int s=0;
        t=2*(n-1)*(m-1)+1;
        for(int i=1;i<=n;i++)
            for(int j=1;j<m;j++) {
                row[i][j]=read();
    //            scanf("%d",&row[i][j]);
            }
        for(int i=1;i<n;i++) {
            for(int j=1;j<=m;j++) {
                col[i][j]=read();
    //            scanf("%d",&col[i][j]);
            }
        }
        for(int i=1;i<n;i++) {
            for(int j=1;j<m;j++) {
                a[i][j]=read();
    //            scanf("%d",&a[i][j]);
            }
        }
        if(n==1){
            int ans = inf;
            for(int j=1;j<m;j++) ans=min(ans,row[1][j]);
            printf("%d
    ",ans);
            return 0;
        }
        if(m==1){
            int ans = inf;
            for(int i=1;i<n;i++) ans=min(ans,col[i][1]);
            printf("%d
    ",ans);
            return 0;
        }
        for(int i=1;i<n;i++){
            for(int j=1;j<m;j++){
                int u = ((i-1)*(m-1)+j)*2,v = u - 1;
                if(u>0&&u<=2*(n-1)*(m-1))  add(u,v,a[i][j]);
                int x = ((i-1)*(m-1)+j+1)*2-1;
                if(x>0&&x<=2*i*(m-1)&&u>0&&u<=2*(n-1)*(m-1))  add(u,x,col[i][j+1]);
                int y = (i*(m-1)+j)*2;
                if(y>0&&y<=2*(n-1)*(m-1))  add(v,y,row[i+1][j]);
    //            printf("i=%d j=%d u=%d v=%d x=%d y=%d
    ",i,j,u,v,x,y);
            }
        }
        for(int i=1;i<n;i++){
            int u = ((i-1)*(m-1)+1)*2-1,v = i*(m-1)*2;
            if(u<0||v<0) continue;
            if(u<=2*(n-1)*(m-1))  add(s,u,col[i][1]);
            if(v<=2*(n-1)*(m-1))  add(t,v,col[i][m]);
        }
    //    printf("
    ");
        for(int j=1;j<m;j++){
            int u = ((n-2)*(m-1)+j)*2-1,v=j*2;
            if(u<0||v<0) continue;
            if(u<=2*(n-1)*(m-1))  add(s,u,row[n][j]);
            if(v<=2*(n-1)*(m-1))  add(t,v,row[1][j]);
    //        printf("u=%d v=%d col=%d row=%d
    ",u,v,row[n-1][j],row[1][j]);
        }
        dij(s);
        printf("%lld
    ",d[t]);
        return 0;
    }
    
    
    
  • 相关阅读:
    Scratch编程:打猎(十)
    Scratch编程:漂亮的时钟(九)
    剑指offer总结一:字符、数字重复问题
    剑指offer:数值的整数次方
    剑指offer:二进制中1的个数
    InnoDB存储引擎与MyIsam存储引擎的区别
    数据库查询慢的原因
    剑指offer:矩形覆盖
    剑指offer:跳台阶问题
    redis键的过期和内存淘汰策略
  • 原文地址:https://www.cnblogs.com/EchoZQN/p/13322359.html
Copyright © 2020-2023  润新知