[TJOI2014]匹配

\(\text{Solution}\)

模板题,二分图带权匹配
第一问费用流即可
第二问考虑枚举最优方案的一条边,删掉,再跑费用流,不能跑出之前的结果说明此边为必经边

\(\text{Code}\)

#include <cstdio>
#include <queue>
#define RE register
#define IN inline
using namespace std;

const int N = 165, INF = 5001;
int n, m, S, T, ansflow, anscost;
int pre[N], edge[N], dis[N], flow[N], vis[N], w[N][N], g[N][N], a[N][N], b[N][N], c[N][N];
queue<int> Q;

IN int spfa()
{
	for(RE int i = S; i <= T; i++) dis[i] = -INF, flow[i] = INF, vis[i] = 0;
	dis[S] = 0, vis[S] = 1, Q.push(S), pre[T] = -1;
	while (!Q.empty())
	{
		int now = Q.front(); Q.pop();
		for(RE int i = S; i <= T; i++)
		if (w[now][i] && dis[now] + b[now][i] > dis[i])
		{
			dis[i] = dis[now] + b[now][i], pre[i] = now, flow[i] = min(flow[now], w[now][i]);
			if (!vis[i]) vis[i] = 1, Q.push(i);
		}
		vis[now] = 0;
	}
	return pre[T] != -1;
}
IN int MCMF(int ty)
{
	int Maxflow = 0, Mincost = 0;
	while (spfa())
	{
		Maxflow += flow[T], Mincost += dis[T] * flow[T];
		int now = T;
		while (now != S) w[pre[now]][now] -= flow[T], w[now][pre[now]] += flow[T], now = pre[now];
		if (Maxflow == n) break;
	}
	if (ty) ansflow = Maxflow, anscost = Mincost;
	else return ((Maxflow == ansflow) && (Mincost == anscost));
}

int main()
{
	freopen("match.in", "r", stdin), freopen("match.out", "w", stdout);
	scanf("%d", &n), S = 0, T = n + n + 1;
	for(RE int i = 1; i <= n; i++)
		for(RE int j = 1; j <= n; j++)
			scanf("%d", &a[i][j + n]), a[j + n][i] = -a[i][j + n], g[i][j + n] = 1;
	for(RE int i = 1; i <= n; i++) g[S][i] = 1, g[i + n][T] = 1;
	for(RE int k = S; k <= T; k++)
		for(RE int l = S; l <= T; l++) w[k][l] = g[k][l], b[k][l] = a[k][l];
	MCMF(1), printf("%d\n", anscost);
	for(RE int k = S; k <= T; k++)
		for(RE int l = S; l <= T; l++) c[k][l] = w[k][l];
	for(RE int i = 1; i <= n; i++)
		for(RE int j = 1; j <= n; j++)
		if (!c[i][j + n])
		{
			for(RE int k = S; k <= T; k++)
				for(RE int l = S; l <= T; l++) w[k][l] = g[k][l], b[k][l] = a[k][l];
			w[i][j + n] = 0, b[i][j + n] = -INF;
			if (!MCMF(0)) printf("%d %d\n", i, j);
		}
}
posted @ 2022-01-14 14:39  leiyuanze  阅读(28)  评论(0编辑  收藏  举报