アイデア:マトリックスの行と列を使用して、マップを作成し、コストフローを実行して、ボードを保存します
#include <bits/stdc++.h>
#define ll long long
#define pi pair<int,int>
#define mk make_pair
#define pb push_back
using namespace std;
const int maxn = 10005;
const int maxm = 1000005;
const int inf = 0x3f3f3f3f;
struct edges{
int to,next,cap,flow,cost;
};
struct MCMF{
int n;
int cnt,head[maxn];
int pre[maxn],d[maxn];
int inq[maxn];
edges edge[maxm];
void init(int n)
{
this->n= n;
this->cnt = 0;
memset(head,-1,sizeof(head));
}
void ads(int u,int v,int cap,int cost){
edge[cnt].to = v;
edge[cnt].cap = cap;
edge[cnt].cost = cost;
edge[cnt].flow = 0;
edge[cnt].next = head[u];
head[u] = cnt++;
}
void AddEdge(int u,int v,int cap,int cost)
{
ads(u,v,cap,cost);
ads(v,u,0,-cost);
}
bool spfa(int s,int t)
{
queue<int>q;
for(int i=0;i<=n;i++)d[i] = inf,pre[i] = -1,inq[i] = 0;
d[s] = 0;
inq[s] = 1;
q.push(s);
while(q.size())
{
int u = q.front();
q.pop();
inq[u] = 0;
for(int i=head[u];~i;i=edge[i].next)
{
int v = edge[i].to;
if(edge[i].cap > edge[i].flow && d[v] > d[u] + edge[i].cost)
{
d[v] = d[u] + edge[i].cost;
pre[v] = i;
if(!inq[v])
{
inq[v] = 1;
q.push(v);
}
}
}
}
if(pre[t] == -1)return false;
return true;
}
int mcmf(int s,int t)
{
int cost = 0;
int flow = 0;
while(spfa(s,t))
{
int mi = inf;
for(int i=pre[t];~i;i = pre[edge[i^1].to])
{
if(mi > edge[i].cap-edge[i].flow)
mi = edge[i].cap - edge[i].flow;
}
for(int i=pre[t];~i;i=pre[edge[i^1].to])
{
edge[i].flow += mi;
edge[i^1].flow -= mi;
cost += edge[i].cost * mi;
}
flow += mi;
}
return cost;
}
void clearflow()
{
for(int i=0;i<cnt;i++)
edge[i].flow = 0,edge[i].cost = -edge[i].cost;
}
}sol;
int main()
{
int n;
scanf("%d",&n);
sol.init(n+n+3);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
int x;
scanf("%d",&x);
sol.AddEdge(i,j+n,1,x);
}
int s = n+n+1,t=s+1;
for(int i=1;i<=n;i++)
{
sol.AddEdge(s,i,1,0);
sol.AddEdge(i+n,t,1,0);
}
printf("%d\n",sol.mcmf(s,t));
sol.clearflow();
printf("%d\n",-sol.mcmf(s,t));
return 0;
}