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 }
原文地址:https://www.cnblogs.com/shangyu/p/2977220.html