浏览器标题切换
浏览器标题切换end

寒假Day16-POJ3422-Kaka's Matrix Travels(最大费用最大流+拆点)

 

思路:最大费用最大流

 

AC代码:

  1 #include<string.h>
  2 #include<iostream>
  3 #include<stdio.h>
  4 #include<algorithm>
  5 #include<queue>
  6 #include<vector>
  7 #include<map>
  8 #include<cmath>
  9 using namespace std;
 10 #define inf 0x3f3f3f3f
 11 const int N=55*55*2;
 12 typedef long long ll;
 13 
 14 struct node
 15 {
 16     int to,nextt;
 17     int cap,flow,cost;
 18 } e[N*N];
 19 
 20 bool book[N];
 21 int pre[10*N],head[10*N],dist[N],a[N][N];
 22 int tot,s,t;
 23 
 24 void add(int u,int v,int cap,int cost)
 25 {
 26     e[tot].to=v;
 27     e[tot].cap=cap;
 28     e[tot].cost=cost;
 29     e[tot].flow=0;
 30     e[tot].nextt=head[u];
 31 
 32     head[u]=tot++;
 33     e[tot].to=u;
 34     e[tot].cap=0;
 35     e[tot].cost=-cost;
 36     e[tot].flow=0;
 37     e[tot].nextt=head[v];
 38     head[v]=tot++;
 39 }
 40 
 41 bool SPFA()
 42 {
 43     for(int i=0; i<=t; i++)
 44     {
 45         dist[i]=inf;
 46         book[i]=0;
 47         pre[i]=-1;
 48     }
 49     book[s]=1;
 50     dist[s]=0;
 51     queue<int>Q;
 52     Q.push(s);
 53     while(!Q.empty())
 54     {
 55         int u=Q.front();
 56         Q.pop();
 57         book[u]=0;
 58         for(int i=head[u]; i!=-1; i=e[i].nextt)
 59         {
 60             int v=e[i].to;
 61             if(e[i].cap>e[i].flow&&dist[v]>dist[u]+e[i].cost)
 62             {
 63                 dist[v]=dist[u]+e[i].cost;
 64                 pre[v]=i;
 65                 if(book[v]==0)
 66                 {
 67                     book[v]=1;
 68                     Q.push(v);
 69                 }
 70             }
 71         }
 72     }
 73     if(dist[t]!=inf)
 74         return 1;
 75     return 0;
 76 }
 77 
 78 int MCMF()
 79 {
 80     int flow=0,cost=0;
 81     while(SPFA())
 82     {
 83         int minn=inf;
 84         for(int i=pre[t]; i!=-1; i=pre[e[i^1].to])
 85             minn=min(minn,e[i].cap-e[i].flow);
 86         for(int i=pre[t]; i!=-1; i=pre[e[i^1].to])
 87         {
 88             e[i].flow+=minn;
 89             e[i^1].flow-=minn;
 90             cost+=e[i].cost*minn;
 91         }
 92         flow+=minn;
 93     }
 94     return cost;
 95 }
 96 
 97 int main()
 98 {
 99     int n,k;
100     while(~scanf("%d %d",&n,&k))
101     {
102         for(int i=1;i<=n;i++)
103         {
104             for(int j=1;j<=n;j++)
105             {
106                 scanf("%d",&a[i][j]);
107             }
108         }
109         tot=0;
110         memset(head,-1,sizeof(head));
111         s=0,t=n*n*2+1;//t=n*n+1
112        /* for(int i=1; i<=n; i++)
113         {
114             for(int j=1; j<=n; j++)
115             {
116                 if(i==n&&j==n)
117                     continue;
118                 if(i==n)//down
119                     add(i+1,j,1,a[i+1][j]);
120                 else if(j==n)//right
121                     add(i,j+1,1,a[i][j+1]);
122                 else
123                 {
124                     add(i,j+1,1,a[i][j+1]);//right
125                     add(i+1,j,1,a[i+1][j]);//down
126                 }
127             }
128         }*/
129         for(int i=1;i<=n;i++)
130         {
131             for(int j=1;j<=n;j++)
132             {
133                 int x=(i-1)*n+j;
134                 add(x*2,x*2+1,1,-a[i][j]);
135                 add(x*2,x*2+1,k-1,0);
136                 if(j!=n)//向下
137                     add(x*2+1,(x+1)*2,k,0);
138                 if(i!=n)//
139                     add(x*2+1,(x+n)*2,k,0);
140             }
141         }
142         add(s,2,k,0);
143         add(2*n*n+1,t,k,0);
144         int mincost=MCMF()*(-1);
145         printf("%d\n",mincost);
146 
147     }
148     return 0;
149 }
View Code

 

posted @ 2020-01-31 23:08  抓水母的派大星  阅读(118)  评论(0编辑  收藏  举报