码迷,mamicode.com
首页 > 其他好文 > 详细

hdu3376 Matrix Again

时间:2018-01-23 22:03:52      阅读:148      评论:0      收藏:0      [点我收藏+]

标签:post   spfa   iostream   markdown   scanf   sizeof   name   int   amp   

最大费用最大流
咋写?取个相反数就可以了……

#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
using namespace std;
int n, a[605][605], ss, tt, hea[750005], cnt, minCost, dis[750005], pre[750005];
queue<int> d;
bool vis[750005];
struct Edge{
    int too, nxt, val, cst;
}edge[2200005];
const int oo=0x3f3f3f3f;
const int dx[]={0, 1, 0};
const int dy[]={0, 0, 1};
int f(int i, int j){
    return (i-1)*n+j;
}
void init(){
    minCost = cnt = 0;
    memset(hea, -1, sizeof(hea));
}
void add_edge(int fro, int too, int val, int cst){
    edge[cnt].nxt = hea[fro];
    edge[cnt].too = too;
    edge[cnt].val = val;
    edge[cnt].cst = cst;
    hea[fro] = cnt++;
}
void addEdge(int fro, int too, int val, int cst){
    add_edge(fro, too, val, cst);
    add_edge(too, fro, 0, -cst);
}
bool spfa(){
    memset(dis, 0x3f, sizeof(dis));
    memset(pre, -1, sizeof(pre));
    d.push(ss);
    vis[ss] = true;
    dis[ss] = 0;
    while(!d.empty()){
        int x=d.front();
        d.pop();
        vis[x] = false;
        for(int i=hea[x]; i!=-1; i=edge[i].nxt){
            int t=edge[i].too;
            if(dis[t]>dis[x]+edge[i].cst && edge[i].val>0){
                dis[t] = dis[x] + edge[i].cst;
                pre[t] = i;
                if(!vis[t]){
                    vis[t] = true;
                    d.push(t);
                }
            }
        }
    }
    return dis[tt]!=oo;
}
void mcmf(){
    while(spfa()){
        int tmp=0x3f3f3f3f;
        for(int i=pre[tt]; i!=-1; i=pre[edge[i^1].too])
            tmp = min(tmp, edge[i].val);
        for(int i=pre[tt]; i!=-1; i=pre[edge[i^1].too]){
            edge[i].val -= tmp;
            edge[i^1].val += tmp;
            minCost += tmp * edge[i].cst;
        }
    }
}
int main(){
    while(scanf("%d", &n)!=EOF){
        init();
        for(int i=1; i<=n; i++)
            for(int j=1; j<=n; j++)
                scanf("%d", &a[i][j]);
        ss = 0; tt = 2 * n * n + 1;
        addEdge(ss, 1, 2, 0);
        addEdge(1, 1+n*n, 1, 0);
        addEdge(f(n,n), f(n,n)+n*n, 1, 0);
        addEdge(f(n,n)+n*n, tt, 2, 0);
        for(int i=1; i<=n; i++)
            for(int j=1; j<=n; j++){
                addEdge(f(i,j), f(i,j)+n*n, 1, -a[i][j]);
                for(int k=1; k<=2; k++){
                    int kx=i+dx[k];
                    int ky=j+dy[k];
                    if(kx>n || ky>n)    continue;
                    addEdge(f(i,j)+n*n, f(kx,ky), oo, 0);
                }
            }
        mcmf();
        printf("%d\n", -minCost);
    }
    return 0;
}

hdu3376 Matrix Again

标签:post   spfa   iostream   markdown   scanf   sizeof   name   int   amp   

原文地址:https://www.cnblogs.com/poorpool/p/8337881.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!