zoukankan      html  css  js  c++  java
  • Baker Vai LightOJ

    在个给出的矩阵从,从左上角走到右下角,然后再从右下角走到左上角,两次不能经过想同的点,每个点都有一个价值,问最大的价值是多少。

    可以把原来的问题化简成从左上角走两条路到右下角,然后把价值加起来,然是这时候我出发点和目标点的价值加了两次,而原本只计算一次,所以最后要减掉,然后建图

    1.超源到(1,1), 容量inf,费用0

    2.自身拆点,(1, 1)和(n, m)容量2,其他点容量1,费用就是本身的价值的负值

    3.(n, m)到超汇,容量inf,费用0

    #include<map>
    #include<set>
    #include<ctime>
    #include<cmath>
    #include<stack>
    #include<queue>
    #include<string>
    #include<vector>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define first fi
    #define second se
    #define lowbit(x) (x & (-x))
    
    typedef unsigned long long int ull;
    typedef long long int ll;
    const double pi = 4.0*atan(1.0);
    const int inf = 0x3f3f3f3f;
    const int maxn = 10050;
    const int maxm = 100000;
    const int mod = 998244353;
    using namespace std;
    
    int n, m, tol, T;
    struct Node {
        int u;
        int v;
        int w;
        int val;
        int next;
    };
    Node node[maxm];
    int head[maxn];
    int dis[maxn];
    int pre[maxn];
    int cap[maxn];
    bool vis[maxn];
    int maps[105][105];
    
    void init() {
        tol = 0;
        memset(node, 0, sizeof node);
        memset(maps, 0, sizeof maps);
        memset(head, -1, sizeof head);
    }
    
    void addnode(int u, int v, int w, int val) {
        node[tol].u = u;
        node[tol].v = v;
        node[tol].w = w;
        node[tol].val = val;
        node[tol].next = head[u];
        head[u] = tol++;
    }
    
    bool spfa(int src, int des, int &flow, int &cost) {
        memset(vis, 0, sizeof vis);
        memset(dis, inf, sizeof dis);
        memset(cap, inf, sizeof cap);
        queue<int > q;
        dis[src] = 0;
        cap[src] = inf;
        pre[src] = src;
        vis[src] = true;
        q.push(src);
        while(!q.empty()) {
            int u = q.front();
            q.pop();
            vis[u] = false;
            for(int i=head[u]; ~i; i=node[i].next) {
                int v = node[i].v;
                if(node[i].w && dis[v] > dis[u] + node[i].val) {
                    dis[v] = dis[u] + node[i].val;
                    pre[v] = i;
                    cap[v] = min(cap[u], node[i].w);
                    if(!vis[v]) {
                        vis[v] = true;
                        q.push(v);
                    }
                }
            }
        }
        if(dis[des] == inf)    return false;
        flow += cap[des];
        cost += cap[des] * dis[des];
        int u = des;
        while(u != src) {
            node[pre[u]].w -= cap[des];
            node[pre[u]^1].w += cap[des];
            u = node[pre[u]].u;
        }
        return true;
    }
    
    int MCMF(int src, int des) {
        int flow = 0;
        int cost = 0;
        while(spfa(src, des, flow, cost));
        return cost;
    }
    
    int main() {
        int cas = 1;
        scanf("%d", &T);
        while(T--) {
            init();
            scanf("%d%d", &n, &m);
            for(int i=1; i<=n; i++)    for(int j=1; j<=m; j++)    scanf("%d", &maps[i][j]);
            int src = 0, des = 2*n*m+1;
            addnode(src, 1, inf, 0);
            addnode(1, src, 0, 0);
            addnode(2*n*m, des, inf, 0);
            addnode(des, 2*n*m, 0, 0);
            int cnt = n * m;
            for(int i=1; i<=n; i++) {
                for(int j=1; j<=m; j++) {
                    if((i==1 && j==1) || (i==n && j == m)) {
                        addnode((i-1)*m+j, (i-1)*m+j+cnt, 2, -maps[i][j]);
                        addnode((i-1)*m+j+cnt, (i-1)*m+j, 0, maps[i][j]);
                    } else {
                        addnode((i-1)*m+j, (i-1)*m+j+cnt, 1, -maps[i][j]);
                        addnode((i-1)*m+j+cnt, (i-1)*m+j, 0, maps[i][j]);
                    }
                    if(i+1<=n) {
                        addnode((i-1)*m+j+cnt, i*m+j, 1, 0);
                        addnode(i*m+j, (i-1)*m+j+cnt, 0, 0);
                    }
                    if(j+1<=m) {
                        addnode((i-1)*m+j+cnt, (i-1)*m+j+1, 1, 0);
                        addnode((i-1)*m+j+1, (i-1)*m+j+cnt, 0, 0);
                    }
                }
            }
            int ans = -MCMF(src, des) - maps[1][1] - maps[n][m];
            printf("Case %d: %d
    ", cas++, ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    java监听者模式
    使用tc编写流量控制脚本
    Android apk集成
    就这样
    嘴不笨来试试??太好玩儿了,看看谁厉害?
    老板的三句话
    电脑设置wifi
    JDBC
    使用git的一般操作
    模板引擎Velocity学习系列
  • 原文地址:https://www.cnblogs.com/Jiaaaaaaaqi/p/9370008.html
Copyright © 2011-2022 走看看