POJ 3422 Kaka's Matrix Travels 费用流

来源:互联网 发布:保卫萝卜源码 编辑:程序博客网 时间:2024/05/18 21:39
View Code
#include<stdio.h>#include<string.h>#include<algorithm>#include<queue>using namespace std;#define maxn 5010#define maxm 10030#define inf 1000000000int min(int a, int b){    return a < b ? a : b;}struct E{    int u, v, c, w, next;}edge[maxm<<3];int head[maxn], tot;int n, m, k;int S, T;void init(){    tot = 0;    memset(head, -1, sizeof(head));}void add(int s, int t, int c, int w){    edge[tot].u = s;    edge[tot].v = t;    edge[tot].c = c;    edge[tot].w = w;    edge[tot].next = head[s];    head[s] = tot++;        edge[tot].u = t;    edge[tot].v = s;    edge[tot].c = 0;    edge[tot].w = -w;    edge[tot].next = head[t];    head[t] = tot++;}bool vis[maxn];int pre[maxn];int dis[maxn];bool spfa(int s, int t, int n){    int i, u, v;    for(i = 0; i <= n; i++)        vis[i] = 0, pre[i] = -1, dis[i] = -inf;    queue<int> q;    q.push(s); vis[s] = 1; dis[s] = 0;    while(!q.empty())    {        u = q.front(); q.pop(); vis[u] = 0;        for(i = head[u]; i != -1; i = edge[i].next)        {            v = edge[i].v;            if(edge[i].c && dis[v] < dis[u] + edge[i].w)            {                dis[v] = dis[u] + edge[i].w;                pre[v] = i;                 if(!vis[v])                {                    vis[v] = 1;                    q.push(v);                }            }        }        }    if(dis[t] == -inf) return 0;    return 1;}int mfmw(int s, int t, int n) {    int i, maxf = 0, minw = 0, aug;    while(spfa(s, t, n))    {        aug = inf;        for(i = pre[t]; i != -1; i = pre[edge[i].u])            aug = min(aug, edge[i].c);        for(i = pre[t]; i != -1; i = pre[edge[i].u])        {            edge[i].c -= aug;            edge[i^1].c += aug;        }        maxf += aug;        minw += dis[t] * aug;    }    return minw;}int main(){    int i, j;    int x, y, z;    while( ~scanf("%d%d", &n, &k))    {        init();        S = 0; T = 2*n*n+1;        add(S, 1, k, 0);        add(n*n*2, T, k, 0);        for(i = 1; i <= n; i++)            for(j = 1; j <= n; j++)            {                scanf("%d", &z);                x = (i-1)*n+j;                add(x, x+n*n, 1, z);                add(x, x+n*n, inf, 0);                if(i < n) add(x+n*n, x+n, inf, 0);                if(j < n) add(x+n*n, x+1, inf, 0);                            }        printf("%d\n", mfmw(S, T, T+1));    }    return 0;}
原创粉丝点击