ZOJ 3862【贪心】【枚举】

题目链接

题目大意是给定n条直线,2*n个点,通过交换任意直线的端点位置使得它们互不相交,容易想到可以通过按照坐标x,y大小排序的规则来交换它们的位置,即可保证所有直线不相交

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int MAXN = 200005;
typedef pair<int, int> P;
struct node
{
	int x, y, id, link;
	node(int _x, int _y, int _id = 0) {
		x = _x, y = _y, id = _id;
	}
	bool operator<(const node &r) const {
		return x == r.x && y < r.y || x < r.x;
	}
};
int p[MAXN];
int main() {
	int T;
	scanf("%d", &T);
	while (T--)
	{
		int n;
		scanf("%d", &n);
		vector<node> v;
		v.push_back({ -INF, -INF, 0 });
		int x, y;
		for (int i = 1; i <= 2 * n; ++i) {
			scanf("%d%d", &x, &y);
			v.push_back(node(x, y, i));
		}
		for (int i = 1; i <= n; ++i) {
			scanf("%d%d", &x, &y);
			v[x].link = y, v[y].link = x;
		}
		sort(v.begin(), v.end());
		for (int i = 1; i <= 2 * n; ++i) {
			p[v[i].id] = i;
		}
		vector<P> ans;
		for (int i = 1; i <= 2 * n; i += 2) {
			if (v[i].link == v[i + 1].id) continue;
			ans.push_back({ v[i].link, v[i + 1].id });
			int j = p[v[i].link];
			v[j].id = v[i + 1].id;
			v[j].link = v[i + 1].link;
			p[v[i + 1].id] = j;
		}
		printf("%zd\n", ans.size());
		for (P i : ans) {
			printf("%d %d\n", i.first, i.second);
		}
	}
}

猜你喜欢

转载自blog.csdn.net/qq_36268036/article/details/79828562
ZOJ