poj3422Kaka's Matrix Travels

http://poj.org/problem?id=3422

最小费用最大流 求的时候把边加为负的 输出的时候再负回来 就变成求的最大费用了

拆点 一个点拆为 i i' i->i'连两条边 一条cap为0 cost为给出的值 另一条cap为INF cost为0 ,i'到右和下分别设置一条边cap为INF cost为0 设置超级源点到1节点 cap为K cost为0

View Code
  1 #include <iostream>

  2 #include<cstdio>

  3 #include<cstring>

  4 #include<algorithm>

  5 #include<stdlib.h>

  6 #include<queue>

  7 #define INF 0xfffffff

  8 #define MN 50500

  9 #define MM 100100

 10 using namespace std;

 11 struct node

 12 {

 13     int u,v,cost,cap,next;

 14 }edge[MM];

 15 int head[MN],t,vis[MN],dist[MN],pp[MN];

 16 void init()

 17 {

 18     t  =0;

 19     memset(head,-1,sizeof(head));

 20 }

 21 void add(int u,int v,int c,int p)

 22 {

 23     edge[t].u = u;

 24     edge[t].v = v;

 25     edge[t].cap = c;

 26     edge[t].cost = p;

 27     edge[t].next = head[u];

 28     head[u] = t++;

 29     edge[t].u = v;

 30     edge[t].v = u;

 31     edge[t].cap = 0;

 32     edge[t].cost = -p;

 33     edge[t].next = head[v];

 34     head[v] = t++;

 35 }

 36 int spfa(int s,int en,int n)

 37 {

 38     int u,v,i;

 39     memset(vis,0,sizeof(vis));

 40     memset(pp,-1,sizeof(pp));

 41     for(i = 0 ; i <= n ; i++)

 42     dist[i] =INF;

 43     queue<int>q;

 44     dist[s] = 0;

 45     vis[s] = 1;

 46     q.push(s);

 47     while(!q.empty())

 48     {

 49         u = q.front();

 50         q.pop();

 51         vis[u] = 0;

 52         //cout<<u<<endl;

 53         for(i = head[u] ; i != -1 ; i = edge[i].next)

 54         {

 55             v = edge[i].v;

 56             if(edge[i].cap&&dist[v]>dist[u]+edge[i].cost)

 57             {

 58                 dist[v]  = dist[u]+edge[i].cost;

 59                 pp[v] = i;

 60                 if(!vis[v])

 61                 {

 62                     vis[v] = 1;

 63                     q.push(v);

 64                 }

 65             }

 66         }

 67     }

 68     //cout<<dist[en]<<endl;

 69     if(dist[en]==INF)

 70     return 0;

 71     return 1;

 72 }

 73 int mcmf(int s,int en,int n)

 74 {

 75     int i,mc=0,minf;

 76     while(spfa(s,en,n))

 77     {

 78         minf = INF+1;

 79         for(i = pp[en] ; i!= -1 ; i = pp[edge[i].u])

 80         {

 81             if(minf>edge[i].cap)

 82             minf = edge[i].cap;

 83         }

 84         for(i = pp[en] ; i != -1; i = pp[edge[i].u])

 85         {

 86             edge[i].cap -= minf;

 87             edge[i^1].cap+=minf;

 88         }

 89         //cout<<minf<<" "<<dist[en]<<endl;

 90         mc+=minf*dist[en];

 91     }

 92     return mc;

 93 }

 94 int main()

 95 {

 96     int i,j,k,n,m,a;

 97     while(cin>>n>>k)

 98     {

 99         init();

100         int s = 0,en = 2*n*n+1;

101         add(s,1,k,0);

102         add(2*n*n,en,k,0);

103         for(i = 1; i <= n ; i++)

104             for(j = 1; j <= n ; j++)

105             {

106                 cin>>a;

107                 add((i-1)*n+j,(i-1)*n+j+n*n,1,-a);

108                 add((i-1)*n+j,(i-1)*n+j+n*n,INF,0);

109                 if(i<n)

110                 add((i-1)*n+j+n*n,i*n+j,INF,0);

111                 if(j<n)

112                 add((i-1)*n+j+n*n,(i-1)*n+j+1,INF,0);

113             }

114         cout<<-mcmf(s,en,en)<<endl;

115     }

116     return 0;

117 }

 

 

你可能感兴趣的:(Matrix)