POJ 2296 Map Labeler (二分+2-SAT判)
2013-11-02 17:54
489 查看
http://poj.org/problem?id=2296
很好的一道2-SAT题
取上为1,取下为0
两个新规则:
a = 0: 这个等价于加边!a->a
a = 1: 这个等价于加边a->!a
当二者y差值<r时,y大的在上,y小的在下
如果等于r时,取i xor j = 1
如果大于r小于2r,则y大的在下,y小的在上这种情况不能存在(and = 0)
其他情况怎么放都可以
View Code
很好的一道2-SAT题
取上为1,取下为0
两个新规则:
a = 0: 这个等价于加边!a->a
a = 1: 这个等价于加边a->!a
当二者y差值<r时,y大的在上,y小的在下
如果等于r时,取i xor j = 1
如果大于r小于2r,则y大的在下,y小的在上这种情况不能存在(and = 0)
其他情况怎么放都可以
//#pragma comment(linker, "/STACK:102400000,102400000") #include<cstdio> #include<iostream> #include<cstring> #include<string> #include<cmath> #include<set> #include<list> #include<map> #include<iterator> #include<cstdlib> #include<vector> #include<queue> #include<stack> #include<algorithm> #include<functional> using namespace std; typedef long long LL; #define ROUND(x) round(x) #define FLOOR(x) floor(x) #define CEIL(x) ceil(x) const int maxn=110; const int maxm=0; const int inf=0x3f3f3f3f; const LL inf64=0x3f3f3f3f3f3f3f3fLL; const double INF=1e30; const double eps=1e-6; /** *2-SAT模板,Modified Edition of LRJ 按字典序排列结果 *输入:按照法则添加边(参数为2*i或者2*i+1) *运行:先init(n),再add(),再solve() *注意:add(2*i,2*j)才行 *输出:mark[](1表示选中),solve()(是否有解) */ //const int maxn = 0; struct TwoSAT { int n; vector<int> G[maxn*2]; bool mark[maxn*2]; int S[maxn*2], c; bool dfs(int x) { if (mark[x^1]) return false; if (mark[x]) return true; mark[x] = true; S[c++] = x; for (int i = 0; i < G[x].size(); i++) if (!dfs(G[x][i])) return false; return true; } void init(int n) { this->n = n; for (int i = 0; i < n*2; i++) G[i].clear(); memset(mark, 0, sizeof(mark)); } /// x AND y = 1 void add_and_one(int x,int y) { G[x^1].push_back(y); G[y^1].push_back(x); G[x].push_back(y); G[y^1].push_back(x^1); G[y].push_back(x); G[x^1].push_back(y^1); } /// x AND y = 0 void add_and_zero(int x,int y) { G[x].push_back(y^1); G[y].push_back(x^1); } /// x OR y = 1 void add_or_one(int x,int y) { G[x^1].push_back(y); G[y^1].push_back(x); } /// x OR y = 0 void add_or_zero(int x,int y) { G[x].push_back(y^1); G[y].push_back(x^1); G[x].push_back(y); G[y^1].push_back(x^1); G[x^1].push_back(y^1); G[y].push_back(x); } /// x XOR y = 1 void add_xor_one(int x,int y) { G[x^1].push_back(y); G[y^1].push_back(x); G[x].push_back(y^1); G[y].push_back(x^1); } /// x XOR y = 0 void add_xor_zero(int x,int y) { G[x^1].push_back(y^1); G[y].push_back(x); G[x].push_back(y); G[y^1].push_back(x^1); } /// x -> y void add_to(int x,int y) { G[x].push_back(y); G[y^1].push_back(x^1); } bool solve() { for(int i = 0; i < n*2; i += 2) if(!mark[i] && !mark[i+1]) { c = 0; if(!dfs(i)) { while(c > 0) mark[S[--c]] = false; if(!dfs(i+1)) return false; } } return true; } } sat; int n; struct Node { int x,y; } node[maxn]; void init() { // } void input() { scanf("%d",&n); for(int i=0; i<n; i++) scanf("%d%d",&node[i].x,&node[i].y); } bool test(int r) { sat.init(n); for(int i=0; i<n; i++) { for(int j=i+1; j<n; j++) { if(abs(node[i].x-node[j].x)>=r||abs(node[i].y-node[j].y)>=2*r) continue; if(abs(node[i].y-node[j].y)<r) { if(node[i].y>node[j].y) { sat.G[2*i+1].push_back(2*i); sat.G[2*j].push_back(2*j+1); } else if(node[i].y<node[j].y) { sat.G[2*j+1].push_back(2*j); sat.G[2*i].push_back(2*i+1); } else { sat.add_xor_one(2*i,2*j); } } else { if(node[i].y>node[j].y) sat.add_and_zero(2*i+1,2*j); else sat.add_and_zero(2*j+1,2*i); } } } if(sat.solve()) return 1; return 0; } void solve() { int L=0,R=inf; while(L<R) { int M=L+(R-L)/2; if(!test(M)) R=M; else L=M+1; } printf("%d\n",L-1); } void output() { // } int main() { // std::ios_base::sync_with_stdio(false); // freopen("in.cpp","r",stdin); int T; scanf("%d",&T); while(T--) { init(); input(); solve(); output(); } return 0; }
View Code
相关文章推荐
- POJ 2296 Map Labeler (二分+2-sat,4级)
- POJ 2296 Map Labeler (二分+2-sat,4级)
- POJ 2296 Map Labeler / ZOJ 2493 Map Labeler / HIT 2369 Map Labeler / UVAlive 2973 Map Labeler(2-sat 二分)
- poj 2296 Map Labeler (2-sat +二分)
- POJ 2296 Map Labeler(2-SAT+二分)
- poj 2296 Map Labeler(2-SAT+二分,构图)
- Map Labeler (poj 2296 二分+2-SAT)
- POJ 2296 Map Labeler 2-SAT 二分
- poj 2296 Map Labeler(二分+2-sat判定)
- POJ 2296 Map Labeler(二分+2-SAT)
- |poj 2296|2-SAT|二分|Map Labeler
- POJ 2296 Map Labeler ( 2-SAT判定 + 二分查找 )
- POJ 2296 - Map Labeler 构图2-sat..注意细节...
- poj 2296 二分+2-sat
- poj 2296 Map Labeler 2-sat
- POJ 2296 Map Labeler(2-sat)
- poj 2296 Map Labeler【二分+2-set】【经典】
- POJ 2296 Map Labeler(二分边长+2-sat判解)(经典题)
- POJ 2296 二分+2-sat
- 【POJ】2296 Map Labeler 2-sat