小数据 AC,大数据 TLE,谁能给我优化过我就给谁两关(简单题)
查看原帖
小数据 AC,大数据 TLE,谁能给我优化过我就给谁两关(简单题)
377873
EricWan楼主2025/1/15 16:45
#include <bits/stdc++.h>
//#include <bits/extc++.h>
#define int long long
#define min(x,y) (((x)<(y))?(x):(y))
#define max(x,y) (((x)>(y))?(x):(y))
#define lowbit(x) ((x)&-(x))
#define abs(x) (((x)<(0))?(-(x)):(x))
#define swap(a,b) a^=b^=a^=b
#define INF 1e18
#define repeat(x) ((x)*((x)-1)/2)
#define MAXN 400005
using namespace std;
int n, m1, m2, k, min2id, now1id, now2id, ans, fa1[MAXN], fa2[MAXN], sz1[MAXN], sz2[MAXN], merge_from[MAXN], merge_to[MAXN], now_connect;
map<int, int> t[MAXN];
vector<int> nodes[MAXN], merge_node[MAXN];
struct edge
{
	int u, v, w;
} e1[MAXN], e2[MAXN];
bool cmpw(edge x, edge y)
{
	return x.w < y.w;
}
int getfa1(int id)
{
	return ((fa1[id] == id) ? id : (fa1[id] = getfa1(fa1[id])));
}
int getfa2(int id)
{
	return ((fa2[id] == id) ? id : getfa2(fa2[id]));
}
void print()
{
	cout << "now_connect = " << now_connect << endl;
	cout << "now1id = " << now1id << endl;
	cout << "min2id = " << min2id << endl;
	cout << "now2id = " << now2id << endl;
	cout << "ans = " << ans << endl;
	cout << "fa1:";
	for (int i = 1; i <= n; i++)
	{
		cout << " " << fa1[i];
	}
	cout << endl;
	cout << "sz1:";
	for (int i = 1; i <= n; i++)
	{
		cout << " " << sz1[i];
	}
	cout << endl;
	cout << "fa2:";
	for (int i = 1; i <= n; i++)
	{
		cout << " " << fa2[i];
	}
	cout << endl;
	cout << "sz2:";
	for (int i = 1; i <= n; i++)
	{
		cout << " " << sz2[i];
	}
	cout << endl;
	for (int i = 1; i <= n; i++)
	{
		cout << i << " (" << nodes[i].size() << ") :";
		for (int j : nodes[i])
		{
			cout << " " << j;
		}
		cout << endl;
	}
	for (int i = 1; i <= n; i++)
	{
		for (pair<int, int> j : t[i])
		{
			cout << i << " " << j.first << " " << j.second << endl;
		}
	}
	cout << endl;
}
// void dfs_split(int id, int k)
// {
	// sz2[id] -= k;
	// if (fa2[id] == id)
	// {
		// return;
	// }
	// dfs_split(fa2[id], k);
// }
signed main()
{
	cin >> n >> m1 >> m2 >> k;
	if (k == 0)
	{
		cout << 0;
		return 0;
	}
	for (int i = 1; i <= m1; i++)
	{
		cin >> e1[i].u >> e1[i].v >> e1[i].w;
	}
	for (int i = 1; i <= m2; i++)
	{
		cin >> e2[i].u >> e2[i].v >> e2[i].w;
	}
	sort(e1 + 1, e1 + m1 + 1, cmpw);
	sort(e2 + 1, e2 + m2 + 1, cmpw);
	e2[m2 + 1].w = ans = 1000000000000000ll;
	min2id = m2 + 1;
	now2id = m2;
	for (int i = 1; i <= n; i++)
	{
		fa1[i] = fa2[i] = i;
		sz1[i] = sz2[i] = 1;
		nodes[i].push_back(i);
	}
	for (int i = 1; i <= m2; i++)
	{
		// cout << "(" << e2[i].u << "," << e2[i].v << "," << e2[i].w << ")\n";
		int x = getfa2(e2[i].u);
		int y = getfa2(e2[i].v);
		if (x == y)
		{
			continue;
		}
		now_connect += sz2[x] * sz2[y];
		if (sz2[x] < sz2[y])
		{
			fa2[x] = y;
			sz2[y] += sz2[x];
			merge_from[i] = x;
			merge_to[i] = y;
			for (int j : nodes[x])
			{
				nodes[y].push_back(j);
				merge_node[i].push_back(j);
			}
			nodes[x].clear();
		}
		else
		{
			fa2[y] = x;
			sz2[x] += sz2[y];
			merge_from[i] = y;
			merge_to[i] = x;
			for (int j : nodes[y])
			{
				nodes[x].push_back(j);
				merge_node[i].push_back(j);
			}
			nodes[y].clear();
		}
		if (now_connect >= k)
		{
			ans = e2[i].w;
			now2id = min2id = i;
			// cout << i << " " << now_connect << endl;
			// print();
			break;
		}
	}
	for (int i = 1; i <= n; i++)
	{
		t[i][getfa2(i)]++;
	}
	// print();
	for (now1id = 1; now1id <= m1; now1id++)
	{
		int x = getfa1(e1[now1id].u);
		int y = getfa1(e1[now1id].v);
		if (x == y)
		{
			continue;
		}
		now_connect += sz1[x] * sz1[y];
		for (pair<int, int> i : t[y])
		{
			now_connect += repeat(i.second);
			now_connect += repeat(t[x][i.first]);
			t[x][i.first] += i.second;
			now_connect -= repeat(t[x][i.first]);
		}
		t[y].clear();
		fa1[y] = x;
		sz1[x] += sz1[y];
		if (now_connect >= k)
		{
			min2id = now2id;
			ans = min(ans, e2[min2id].w + e1[now1id].w);
		}
		// cout << "add 1 edge " << now1id << endl;
		// print();
		while (now2id >= 1 && now_connect >= k)
		{
			if (merge_node[now2id].size() == 0)
			{
				now2id--;
				if (now_connect >= k)
				{
					min2id = now2id;
					ans = min(ans, e2[min2id].w + e1[now1id].w);
				}
				continue;
			}
			int mf = merge_from[now2id];
			int mt = merge_to[now2id];
			fa2[mf] = mf;
			// dfs_split(mt, sz2[mf]);
			sz2[mt] -= sz2[mf];
			now_connect -= sz2[mt] * sz2[mf];
			for (int i = 1; i <= sz2[mf]; i++)
			{
				nodes[mt].pop_back();
			}
			nodes[mf] = merge_node[now2id];
			for (int i : nodes[mf])
			{
				int fai = getfa1(i);
				now_connect += repeat(t[fai][mt]);
				t[fai][mt]--;
				now_connect -= repeat(t[fai][mt]);
				now_connect += repeat(t[fai][mf]);
				t[fai][mf]++;
				now_connect -= repeat(t[fai][mf]);
				if (t[fai][mt] == 0)
				{
					t[fai].erase(mt);
				}
			}
			now2id--;
			if (now_connect >= k)
			{
				min2id = now2id;
				ans = min(ans, e2[min2id].w + e1[now1id].w);
			}
			// int x = e2[now2id].u;
			// int y = e2[now2id].v;
			// x = getfa(x);
			// y = getfa(y);
			// if (fa2[y] == x)
			// {
				// swap(x, y);
			// }
			// cout << "del 2 edge " << now2id + 1 << endl;
			// print();
		}
		// cout << now1id << " " << now2id << " " << min2id << " " << now_connect << endl;
	}
	if (ans >= 1000000000000000ll)
	{
		cout << -1;
		return 0;
	}
	cout << ans;
	return 0;
}
2025/1/15 16:45
加载中...