题意就不说了,今天的比赛的时候没写,4个小时。sdu太吊。
MCMF当做模板使用吧,
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
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 }