Kaka's Matrix Travels

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

  1 #include <stdio.h>
  2 #include <algorithm>
  3 #include <string.h>
  4 #include <queue>
  5 using namespace std;
  6 const int INF = 1<<28;
  7 const int N=50050;
  8 int Map[55][55],dis[N];
  9 int head[N],pre[N];
 10 bool vis[N];
 11 int cnt = 0;
 12 int ans = 0;
 13 int n;
 14 struct node
 15 {
 16     int u,v,c,f;
 17     int next;
 18 
 19 } edge[N];
 20 void add(int u,int v,int c,int f)
 21 {
 22     edge[cnt].u = u;
 23     edge[cnt].v = v;
 24     edge[cnt].c = c;
 25     edge[cnt].f = f;
 26     edge[cnt].next = head[u];
 27     head[u] = cnt++;
 28     edge[cnt].u = v;
 29     edge[cnt].v = u;
 30     edge[cnt].c = -c;
 31     edge[cnt].f = 0;
 32     edge[cnt].next = head[v];
 33     head[v] = cnt++;
 34 }
 35 int spfa()
 36 {
 37     for (int i = 0; i <= n*n*2+1; i++)
 38     {
 39         dis[i] = INF;
 40         pre[i] = -1;
 41         vis[i] = false;
 42     }
 43     dis[n*n*2] = 0;
 44     queue<int>q;
 45     q.push(n*n*2);
 46     vis[n*n*2] = true;
 47     while(!q.empty())
 48     {
 49         int u = q.front();
 50         vis[u] = false;
 51         q.pop();
 52         for (int j = head[u]; j!=-1; j=edge[j].next)
 53         {
 54             if (edge[j].f > 0&&dis[edge[j].v] > dis[u]+ edge[j].c)
 55             {
 56                 pre[edge[j].v] = j;
 57                 dis[edge[j].v] = dis[u]+ edge[j].c;
 58                 if (!vis[edge[j].v])
 59                 {
 60                     q.push(edge[j].v);
 61                     vis[edge[j].v] = true;
 62                 }
 63             }
 64         }
 65     }
 66     if (pre[n*n*2+1]==-1)
 67         return 0;
 68     return 1;
 69 }
 70 void MCMF()
 71 {
 72     while(spfa())
 73     {
 74         int Minflow = INF;
 75         int j = pre[n*n*2+1];
 76         while(j!=-1)
 77         {
 78             Minflow = min(Minflow,edge[j].f);
 79             j = pre[edge[j].u];
 80         }
 81         j = pre[n*n*2+1];
 82         while(j!=-1)
 83         {
 84             edge[j].f-=Minflow;
 85             edge[j^1].f+=Minflow;
 86             ans+=Minflow*edge[j].c;
 87             j = pre[edge[j].u];
 88         }
 89     }
 90 }
 91 int main()
 92 {
 93     int k;
 94     scanf("%d%d",&n,&k);
 95     memset(Map,0,sizeof(Map));
 96     memset(head,-1,sizeof(head));
 97     for (int i = 1; i <= n; i++)
 98     {
 99         for (int j = 1; j <= n; j++)
100         {
101             scanf("%d",&Map[i][j]);
102         }
103     }
104     for (int i = 1; i <= n; i++)//拆点
105     {
106         for (int j = 1; j <= n; j++)
107         {
108             int u = (i-1)*n+j-1;
109             add(2*u,2*u+1,-Map[i][j],1);//加边
110             add(2*u,2*u+1,0,k-1);
111         }
112     }
113     for (int i = 1; i <= n; i++)//向右加边
114     {
115         for (int j = 1; j < n; j++)
116         {
117             int u = (i-1)*n+j-1;
118             add(2*u+1,(u+1)*2,0,k);
119         }
120     }
121     for (int i = 1; i < n; i++)//向下加边
122     {
123         for (int j = 1; j <= n; j++)
124         {
125             int u = (i-1)*n+j-1;
126             add(2*u+1,(u+n)*2,0,k);
127         }
128     }
129     add(n*n*2,0,0,k);//加源点
130     add(n*n*2-1,n*n*2+1,0,k);//加终点
131     MCMF();
132     printf("%d\n",-ans);
133     return 0;
134 }
View Code

 

 

posted @ 2014-02-13 13:57  N_ll  阅读(155)  评论(0编辑  收藏  举报