FZU 2143 最小费用(非最大流)

 

题意就不说了,今天的比赛的时候没写,4个小时。sdu太吊。

 

MCMF当做模板使用吧,

 

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <algorithm>
  5 #include <queue>
  6 using namespace std;
  7 
  8 const int E = 50010;
  9 const int oo = 0x7fffffff;
 10 const int inf = 10000;
 11 const int maxn = 1010;
 12 
 13 struct edge
 14 {
 15     int next,v,flow,cost;
 16 } e[E];
 17 struct MCMF
 18 {
 19     int head[maxn];
 20     queue<int> q;
 21     int cnt, S, T;
 22     void init(int __S,int __T)
 23     {
 24         S = __S;
 25         T = __T;
 26         memset(head,-1,sizeof(head));
 27         cnt = 0;
 28     }
 29     void add(int u,int v,int flow,int cost)
 30     {
 31         e[cnt].v = v;
 32         e[cnt].flow = flow;
 33         e[cnt].cost = cost;
 34         e[cnt].next = head[u];
 35         head[u] = cnt ++;
 36     }
 37 
 38     void AddEdge(int u,int v,int flow,int cost)
 39     {
 40         add(u,v,flow,cost);
 41         add(v,u,0, -cost);
 42     }
 43 
 44 
 45 
 46     int dis[maxn],cc[maxn],visit[maxn],pre[maxn],dd[maxn];
 47 
 48     int spfa()
 49     {
 50         fill(dis,dis + T + 1, oo);
 51         dis[S] = 0;
 52         pre[S] = -1;
 53         q.push(S);
 54         while(!q.empty())
 55         {
 56             int u = q.front();
 57             q.pop();
 58             visit[u] = 0;
 59             for(int i = head[u]; i != -1; i = e[i].next)
 60             {
 61                 if(e[i].flow > 0 && dis[e[i].v] > dis[u] + e[i].cost)
 62                 {
 63                     dis[e[i].v] = dis[u] + e[i].cost;
 64                     pre[e[i].v] = u;
 65                     cc[e[i].v] = i;
 66                     dd[e[i].v] = e[i].cost;
 67                     if(!visit[e[i].v])
 68                     {
 69                         q.push(e[i].v);
 70                         visit[e[i].v] = 1;
 71                     }
 72                 }
 73             }
 74         }
 75         return dis[T] < 0;
 76     }
 77 
 78     int argument()
 79     {
 80         int aug = oo;
 81         int u,v;
 82         int ans = 0;
 83         for(u = pre[v = T]; v != S; v = u, u = pre[v])
 84             if(e[cc[v]].flow < aug) aug = e[cc[v]].flow;
 85         for(u = pre[v = T]; v != S; v = u, u = pre[v])
 86         {
 87             e[cc[v]].flow -= aug;
 88             e[cc[v] ^ 1].flow += aug;
 89             ans += dd[v] * aug;
 90         }
 91         return ans;
 92     }
 93 
 94     int mcmf()
 95     {
 96         int res = 0;
 97         memset(visit,0,sizeof(visit));
 98         while(spfa()) res += argument();
 99         return res;
100     }
101 } MC;
102 
103 
104 int N,M,K;
105 int b[11][11];
106 
107 int main()
108 {
109     int cas, cast = 0;
110     scanf("%d",&cas);
111     while (cas--)
112     {
113         scanf("%d%d%d",&N,&M,&K);
114         for (int i=1;i<=N;i++)
115         {
116             for (int j=1;j<=M;j++)
117             {
118                 scanf("%d",&b[i][j]);
119             }
120         }
121 
122 
123         int nn = N * M + 2, s = 0, t = N*M + 1;
124         MC.init(s,t);
125         int ans = 0;
126         for (int i=1;i<=N;i++)
127         for (int j=1;j<=M;j++)
128         {
129             ans += b[i][j] * b[i][j];
130             int p = i*M - M + j;
131             if ((i+j)%2==0){
132                 for (int k=1;k<=K;k++)
133                 {
134                     int tmp = 2 * k - 1 - 2 * b[i][j];
135                     MC.AddEdge(s,p, 1,tmp);
136                 }
137                 int pp = 0;
138                 if (i<N)
139                 {
140                     pp = p + M;
141                     MC.AddEdge(p,pp,inf,0);
142                 }
143                 if (i>1)
144                 {
145                     pp = p - M;
146                     MC.AddEdge(p,pp,inf,0);
147                 }
148                 if (j<M)
149                 {
150                     pp = p + 1;
151                     MC.AddEdge(p,pp,inf,0);
152                 }
153                 if (j>1)
154                 {
155                     pp = p - 1;
156                     MC.AddEdge(p,pp,inf,0);
157                 }
158             }else{
159                 for (int k=1;k<=K;k++)
160                 {
161                     int tmp = 2 * k - 1 - 2 * b[i][j];
162                     MC.AddEdge(p,t, 1,tmp);
163                 }
164             }
165         }
166       //  MC.AddEdge(s,t,INF,0);
167         printf("Case %d: %d\n",++cast, ans + MC.mcmf());
168     }
169     return 0;
170 }
hdu2143

 

转载于:https://www.cnblogs.com/wangsouc/articles/3717729.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值