zoukankan      html  css  js  c++  java
  • begin.BZOJ 1383: 三取方格数

    题目链接:传送门

    题目大意:给你一个矩阵,每个格子有一个值,现在你要从左上角走到右下角(走3次),使得经过路径的权值和最大。

         每个格子的值只能取一次,取完后变为0,输出走完三次后最大的权值和。

    题目思路:费用流做法,对于每个格子拆点,因为权值只有第一次能取,所以将每个格子拆为两条边,一条边容量为1,费用为格子的权值,另一条边容量2,费用0。

           相邻格子间连边,容量3,费用0。再建立源点S 与左上角第一个格子连边容量3,费用0。汇点 T 与右下角最后一个格子连边,容量3,费用0。跑费用流累加费用即可。

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <algorithm>
    #include <cstring>
    #include <stack>
    #include <cctype>
    #include <queue>
    #include <string>
    #include <vector>
    #include<functional>
    #include <set>
    #include <map>
    #include <climits>
    #define lson root<<1,l,mid
    #define rson root<<1|1,mid+1,r
    #define fi first
    #define se second
    #define ping(x,y) ((x-y)*(x-y))
    #define mst(x,y) memset(x,y,sizeof(x))
    #define mcp(x,y) memcpy(x,y,sizeof(y))
    using namespace std;
    #define gamma 0.5772156649015328606065120
    #define MOD 1000000007
    #define inf 0x3f3f3f3f
    #define N 100005
    #define maxn 10005
    typedef pair<int,int> PII;
    typedef long long LL;
     
    int n,m,ans,S,T,cost;
    char pic[55][55];
    int num[55][55];
    int vis[maxn],pre[maxn],d[maxn];
    struct Node{
        int to,next,f,c;
        Node(){}
        Node(int a,int b,int _c,int d):to(a),next(b),f(_c),c(d){}
    }node[N];int head[maxn],hcnt;
    queue<int>q;
    inline void add(int x,int y,int f,int c){
        node[hcnt]=Node(y,head[x],f,c);head[x]=hcnt++;
        node[hcnt]=Node(x,head[y],0,-c);head[y]=hcnt++;
    }
    void init(){
        mst(head,-1);hcnt=0;
        S=0;T=n*n*2+1;
        add(S,1,3,0);add(num[n][n]+n*n,T,3,0);
        for(int i=1;i<=n;++i)for(int j=1;j<=n;++j){
            if(i+1<=n)add(num[i][j]+n*n,num[i+1][j],3,0);
            if(j+1<=n)add(num[i][j]+n*n,num[i][j+1],3,0);
            add(num[i][j],num[i][j]+n*n,2,0);
            add(num[i][j],num[i][j]+n*n,1,pic[i][j]-'0');
        }
    }
    int spfa(){
        pre[S]=pre[T]=-1;
        mst(vis,0);mst(d,-1);d[S]=0;
        q.push(S);
        while(!q.empty()){
            int x=q.front();q.pop();
            vis[x]=0;
            for(int i=head[x];~i;i=node[i].next){
                int e=node[i].to;
                if(node[i].f&&d[e]<d[x]+node[i].c){
                    pre[e]=i^1;
                    d[e]=d[x]+node[i].c;
                    if(!vis[e]){
                        q.push(e);
                        vis[e]=1;
                    }
                }
            }
        }
        return pre[T]!=-1;
    }
    void mcmf(){
        init();
        while(spfa()){
            int fl=inf;
            for(int i=pre[T];~i;i=pre[node[i].to])
                fl=min(fl,node[i^1].f);
            for(int i=pre[T];~i;i=pre[node[i].to]){
                node[i].f+=fl;node[i^1].f-=fl;
            }
            cost+=d[T];
        }
        printf("%d
    ",cost);
    }
    int main() {
        int i,j,group,x,y,Case=0;
        scanf("%d",&n);
        for(i=1;i<=n;++i){
            scanf("%s",pic[i]+1);
            for(j=1;j<=n;++j)
                num[i][j]=++Case;
        }
        mcmf();
        return 0;
    }

         

  • 相关阅读:
    Interview with BOA
    Java Main Differences between HashMap HashTable and ConcurrentHashMap
    Java Main Differences between Java and C++
    LeetCode 33. Search in Rotated Sorted Array
    LeetCode 154. Find Minimum in Rotated Sorted Array II
    LeetCode 153. Find Minimum in Rotated Sorted Array
    LeetCode 75. Sort Colors
    LeetCode 31. Next Permutation
    LeetCode 60. Permutation Sequence
    LeetCode 216. Combination Sum III
  • 原文地址:https://www.cnblogs.com/Kurokey/p/5726902.html
Copyright © 2011-2022 走看看