zoukankan      html  css  js  c++  java
  • HDU2686-Matrix & HDU3376-Matrix Again(费用流)

    比较简单的题了。

    只需从左上角到右下角找两条路就可以了。

    因为每个点只能走一次,所以拆点,限制流量为1。

    因为求的是最大值,所以权值取反求最小值。

    因为第一个点和最后一个点经过两次,只算一次,最后要减去。

    ps:数组还是开大点好。。。。不知道什么时候就SB了。。。

    注意汇点可能不是最后一个点(模板的问题。。

    注意初始化的范围。。。。

    matrix again只是数据大了,算法不用改。。。无聊。。。。

    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <string>
    #include <vector>
    #include <bitset>
    #include <cstdio>
    #include <queue>
    #include <stack>
    #include <cmath>
    #include <list>
    #include <map>
    #include <set>
    #define pk(x) printf("%d
    ", x)
    using namespace std;
    #define PI acos(-1.0)
    #define EPS 1E-6
    #define clr(x,c) memset(x,c,sizeof(x))
    //#pragma comment(linker, "/STACK:102400000,102400000")
    typedef long long ll;
    
    const int MAXV = 2000;
    const int INF = 1<<30;
    
    struct Edge { int to, cap, cost, rev; };
    vector<Edge> G[MAXV];
    int dist[MAXV], prv[MAXV], pre[MAXV], in[MAXV];
    queue<int> que;
    
    void addedge(int from, int to, int cap, int cost) {
        G[from].push_back((Edge){to, cap, cost, G[to].size()});
        G[to].push_back((Edge){from, 0, -cost, G[from].size()-1});
    }
    
    int min_cost_max_flow(int s, int t) { //, int f) {
        int res = 0;
        int f = 0;
        while (1) { //f > 0) {
            for (int i = 1; i <= t; ++i) dist[i] = INF, in[i] = 0;
            dist[s] = 0;
            while (!que.empty()) que.pop();
            in[s] = 1;
            que.push(s);
    
            while (!que.empty()) {
                int u = que.front(); que.pop(); in[u] = 0;
                for (int i = 0; i < G[u].size(); ++i) {
                    Edge &e = G[u][i];
                    if (e.cap > 0 && dist[e.to] > dist[u] + e.cost) {
                        dist[e.to] = dist[u] + e.cost;
    
                        prv[e.to] = u;
                        pre[e.to] = i;
                        if (in[e.to] == 0) {
                            in[e.to] = 1;
                            que.push(e.to);
                        }
                    }
                }
            }
    
            if (dist[t] == INF) break; //return -1;
    
            int d = INF; // d = f;
            for (int v = t; v != s; v = prv[v]) {
                d = min(d, G[prv[v]][pre[v]].cap);
            }
            f += d;
            res += d * dist[t];
            for (int v = t; v != s; v = prv[v]) {
                Edge &e = G[prv[v]][pre[v]];
                e.cap -= d;
                G[v][e.rev].cap += d;
            }
        }
        return res;
        //return f;
    }
    
    int n;
    int getid1(int x, int y) { return x*n+y+1; }
    int getid2(int x, int y) { return x*n+y+n*n+1; }
    int a[30][30];
    int main()
    {
        while (~scanf("%d", &n)) {
            for (int i = 0; i < n; ++i) {
                for (int j = 0; j < n; ++j) {
                    scanf("%d", &a[i][j]);
                }
            }
            for (int i = 0; i <= 2*n*n; ++i) G[i].clear();
            for (int i = 0; i < n; ++i) {
                for (int j = 0; j < n; ++j) {
                    if (i+j == 0) addedge(getid1(i,j), getid2(i,j), 2, -a[i][j]);
                    else if (i+j == n*2 - 2) addedge(getid1(i,j), getid2(i, j), 2, -a[i][j]);
                    else addedge(getid1(i, j), getid2(i, j), 1, -a[i][j]);
                    if (i+1<n) addedge(getid2(i, j), getid1(i+1, j), 1, 0);
                    if (j+1<n) addedge(getid2(i, j), getid1(i, j+1), 1, 0);
                }
            }
            printf("%d
    ", -min_cost_max_flow(getid1(0,0), getid2(n-1,n-1)) - a[0][0] - a[n-1][n-1]);
        }
        return 0;
    }
    hdu2686
    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <string>
    #include <vector>
    #include <bitset>
    #include <cstdio>
    #include <queue>
    #include <stack>
    #include <cmath>
    #include <list>
    #include <map>
    #include <set>
    #define pk(x) printf("%d
    ", x)
    using namespace std;
    #define PI acos(-1.0)
    #define EPS 1E-6
    #define clr(x,c) memset(x,c,sizeof(x))
    //#pragma comment(linker, "/STACK:102400000,102400000")
    typedef long long ll;
    
    const int MAXV = 610*610*2+2;
    const int INF = 1<<30;
    
    struct Edge { int to, cap, cost, rev; };
    vector<Edge> G[MAXV];
    int dist[MAXV], prv[MAXV], pre[MAXV], in[MAXV];
    queue<int> que;
    
    void addedge(int from, int to, int cap, int cost) {
        G[from].push_back((Edge){to, cap, cost, G[to].size()});
        G[to].push_back((Edge){from, 0, -cost, G[from].size()-1});
    }
    
    int min_cost_max_flow(int s, int t) { //, int f) {
        int res = 0;
        int f = 0;
        while (1) { //f > 0) {
            for (int i = 1; i <= t; ++i) dist[i] = INF, in[i] = 0;
            dist[s] = 0;
            while (!que.empty()) que.pop();
            in[s] = 1;
            que.push(s);
    
            while (!que.empty()) {
                int u = que.front(); que.pop(); in[u] = 0;
                for (int i = 0; i < G[u].size(); ++i) {
                    Edge &e = G[u][i];
                    if (e.cap > 0 && dist[e.to] > dist[u] + e.cost) {
                        dist[e.to] = dist[u] + e.cost;
    
                        prv[e.to] = u;
                        pre[e.to] = i;
                        if (in[e.to] == 0) {
                            in[e.to] = 1;
                            que.push(e.to);
                        }
                    }
                }
            }
    
            if (dist[t] == INF) break; //return -1;
    
            int d = INF; // d = f;
            for (int v = t; v != s; v = prv[v]) {
                d = min(d, G[prv[v]][pre[v]].cap);
            }
            f += d;
            res += d * dist[t];
            for (int v = t; v != s; v = prv[v]) {
                Edge &e = G[prv[v]][pre[v]];
                e.cap -= d;
                G[v][e.rev].cap += d;
            }
        }
        return res;
        //return f;
    }
    
    inline int Scan()
    {
        char ch = getchar();
        int data = 0;
        while (ch < '0' || ch > '9') ch = getchar();
        do {
            data = data*10 + ch-'0';
            ch = getchar();
        } while (ch >= '0' && ch <= '9');
        return data;
    }
    
    int n;
    int getid1(int x, int y) { return x*n+y+1; }
    int getid2(int x, int y) { return x*n+y+n*n+1; }
    int a[600][600];
    int main()
    {
        while (~scanf("%d", &n)) {
            int maxn = 2*n*n;
            for (int i = 0; i <= maxn; ++i) G[i].clear();
            for (int i = 0; i < n; ++i) {
                for (int j = 0; j < n; ++j) {
                    a[i][j] = Scan();
                    if (i+j == 0 || i+j == n*2-2) addedge(getid1(i,j), getid2(i,j), 2, -a[i][j]);
                    else addedge(getid1(i, j), getid2(i, j), 1, -a[i][j]);
                    if (i+1<n) addedge(getid2(i, j), getid1(i+1, j), 1, 0);
                    if (j+1<n) addedge(getid2(i, j), getid1(i, j+1), 1, 0);
                }
            }
            printf("%d
    ", -min_cost_max_flow(getid1(0,0), getid2(n-1,n-1)) - a[0][0] - a[n-1][n-1]);
        }
        return 0;
    }
    hdu3376
  • 相关阅读:
    微信小程序里自定义组件,canvas组件没有效果
    微信小程序填坑之路(三):布局适配方案(rpx、px、vw、vh)
    小程序checkbox调整大小
    css让文字竖着排列 writing-mode 属性
    微信小程序 位置定位position详解,相对定位relative,绝对定位absolute相关问题
    小程序国际化实现方式
    mybatis plus 学习
    cesium js学习一加载三维模型【转】
    cesiumjs学习笔记之三——cesium-navigation插件 【转】
    局域网Cesium离线影像及瓦片影像地图加载【转】
  • 原文地址:https://www.cnblogs.com/wenruo/p/5873155.html
Copyright © 2011-2022 走看看