【2019 ICPC Brazil Regional】G.Getting Confidence (n^3 KM)

本KM代碼可以通過2019ICPC南京的J題,是真正的n^3,可放心使用。
2019 Nanjing Regional 被卡了KM之後,又在訓練的時候做到了一個KM的題…
於是就搞了一份bfs 的 KM…只測了這一個題,還不知道複雜度具體是多少。
這個題是算乘法的最大值,轉化成log就直接最大權匹配了…
n是100,這題應該沒卡費用流。

(我自閉了,我搞了份dfs的KM發現CF上只跑了31MS,而本代碼跑了46MS…)
不管了,先放上代碼再說…
(我繼續研究複雜度去了…)

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
#define FOR(i, x, y) for (LL i = (x), _##i = (y); i < _##i; ++i)
#define FORD(i, x, y) for (LL i = (x), _##i = (y); i > _##i; --i)
#ifdef zerol
#define dbg(args...) do { cout << "\033[32;1m" << #args<< " -> "; err(args); } while (0)
void err() { cout << "\033[39;0m" << endl; }
template<typename T, typename... Args>
void err(T a, Args... args) { cout << a << ' '; err(args...); }
#else
#define dbg(...)
#endif
// -----------------------------------------------------------------------------
const int maxn = 110;
const double INF = 1e18;
int n,nl,nr,m;
double a[maxn][maxn];
double slk[maxn],sl[maxn],sr[maxn];
int pre[maxn],match[maxn];
bool vis[maxn];
void bfs(int s)
{
	for(int i=0;i<maxn;i++)
	{
		slk[i] = INF;
		vis[i] = 0;
		pre[i] = 0;
	}
	int u,nt,nw;
	double d;
	match[u=0] = s;
	do
	{
		nw = match[u];
		d = slk[0];
		vis[u] = true;
		for(int v=1;v<=n;v++)
		{
			if(!vis[v])
			{
				if(sl[nw]+sr[v]-a[nw][v]<slk[v]) 
				{
					slk[v] = sl[nw]+sr[v]-a[nw][v];
					pre[v] = u;
				}
				if(d>slk[v])
				{
					d = slk[v];
					nt = v;
				}
			}
		}
		for(int i=0;i<=n;i++)
		{
			if(vis[i])
			{
				sl[match[i]] -= d;
				sr[i] += d;
			}
			else slk[i] -= d;
		}
		u = nt;
	}while(match[u]);
	while(u)
	{
		match[u] = match[pre[u]];
		u = pre[u];
	}
}
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			double x;
			scanf("%lf",&x);
			a[i][j] = max(a[i][j],log2(x));
			sl[i] = max(sl[i],a[i][j]);
		}
	}
	for(int i=1;i<=n;i++) bfs(i);
	for(int i=1;i<=n;i++) printf("%d%c",match[i]," \n"[i==n]);
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章