POJ 2296 Map Labeler(2-sat)
生活随笔
收集整理的這篇文章主要介紹了
POJ 2296 Map Labeler(2-sat)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
POJ 2296 Map Labeler
題目鏈接
題意:
坐標軸上有N個點。要在每一個點上貼一個正方形,這個正方形的橫豎邊分別和x,y軸平行,而且要使得點要么在正方形的上面那條邊的中點,或者在以下那條邊的中點。而且隨意兩個點的正方形都不重疊(能夠重邊)。問正方形最大邊長能夠多少?
思路:顯然的2-sat問題,注意推斷兩個矩形相交的地方,細節
代碼:
#include <cstdio> #include <cstring> #include <cstdlib> #include <vector> #include <algorithm> using namespace std;const int MAXNODE = 205;struct TwoSet {int n;vector<int> g[MAXNODE * 2];bool mark[MAXNODE * 2];int S[MAXNODE * 2], sn;void init(int tot) {n = tot * 2;for (int i = 0; i < n; i += 2) {g[i].clear();g[i^1].clear();}memset(mark, false, sizeof(mark));}void add_Edge(int u, int uval, int v, int vval) {u = u * 2 + uval;v = v * 2 + vval;g[u^1].push_back(v);g[v^1].push_back(u);}void delete_Edge(int u, int uval, int v, int vval) {u = u * 2 + uval;v = v * 2 + vval;g[u^1].pop_back();g[v^1].pop_back();}bool dfs(int u) {if (mark[u^1]) return false;if (mark[u]) return true;mark[u] = true;S[sn++] = u;for (int i = 0; i < g[u].size(); i++) {int v = g[u][i];if (!dfs(v)) return false;}return true;}bool solve() {for (int i = 0; i < n; i += 2) {if (!mark[i] && !mark[i + 1]) {sn = 0;if (!dfs(i)){for (int j = 0; j < sn; j++)mark[S[j]] = false;sn = 0;if (!dfs(i + 1)) return false;}}}return true;} } gao;const int N = 105;int t, n; struct Point {int x, y;void read() {scanf("%d%d", &x, &y);x *= 2;} } p[N];bool judge(int len) {gao.init(n);for (int i = 0; i < n; i++) {for (int j = i + 1; j < n; j++) {if (p[i].x + len <= p[j].x - len || p[j].x + len <= p[i].x - len) continue;for (int x = 0; x < 2; x++) {for (int y = 0; y < 2; y++) {int y1, y2, y3, y4;if (x == 0) {y1 = p[i].y - len;y2 = p[i].y;} else {y1 = p[i].y;y2 = p[i].y + len;}if (y == 0) {y3 = p[j].y - len;y4 = p[j].y;} else {y3 = p[j].y;y4 = p[j].y + len;}if ((y1 >= y3 && y1 < y4) || (y2 > y3 && y2 <= y4)|| (y3 >= y1 && y3 < y2)|| (y3 > y2 && y4 <= y2))gao.add_Edge(i, x, j, y);}}}}return gao.solve(); }int main() {scanf("%d", &t);while (t--) {scanf("%d", &n);for (int i = 0; i < n; i++)p[i].read();int l = 0, r = 20000;while (l < r) {int mid = (l + r) / 2;if (judge(mid)) l = mid + 1;else r = mid;}printf("%d\n", l - 1);}return 0; }
轉載于:https://www.cnblogs.com/clnchanpin/p/7058844.html
總結
以上是生活随笔為你收集整理的POJ 2296 Map Labeler(2-sat)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 合并两个有序数组为一个新的有序数组
- 下一篇: C#获取当前程序运行路径的方法集合