2SAT+uva1146
来源:互联网 发布:js在数组的末尾加上空 编辑:程序博客网 时间:2024/05/21 13:59
学习了一下2SAT,以前看不太明白的,现在大概看明白了,顺便敲一下训练指南上的飞机调度问题
#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<cmath>#include<vector>using namespace std;const int maxn=20100;int n,T[maxn][2];struct twoset{ int n; vector<int> g[maxn*2]; bool mark[maxn*2]; int S[maxn*2],c; void init(int n) { this->n=n; memset(mark,0,sizeof(mark)); for(int i=0;i<n*2;i++)g[i].clear(); } 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++) { int v=g[x][i]; if(!dfs(v))return false; } return true; } void add_clause(int x,int vx,int y,int vy) { x=x*2+vx; y=y*2+vy; g[x^1].push_back(y); g[y^1].push_back(x); } 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; }}a;bool can(int mid){ a.init(n); for(int i=0;i<n;i++) for(int x=0;x<2;x++) for(int j=i+1;j<n;j++) for(int y=0;y<2;y++) if(abs(T[i][x]-T[j][y])<mid) a.add_clause(i,x^1,j,y^1); return a.solve();}int main(){ #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); #endif while(scanf("%d",&n)!=EOF&&n) { int L=0,R=0,mid; for(int i=0;i<n;i++) for(int j=0;j<2;j++) { cin>>T[i][j]; R=max(R,T[i][j]); } while(L<R) { mid=L+(R-L+1)/2; if(can(mid))L=mid; else R=mid-1; } cout<<L<<endl; } return 0;}
还可以用tarjan算法(转载)
#include <cstdio> #include <cstring> #include <algorithm> #include <cstdlib> #include <vector> #include <stack> using namespace std; const int N = 4444; int pre[N], sccno[N], lowlink[N], dfs_clock, scc_cnt, T[N][2], n; stack<int> S; vector<int> G[N]; void add_edge(int x, int xval, int y, int yval){ x = x * 2 + xval; y = y * 2 + yval; G[x ^ 1].push_back(y); G[y ^ 1].push_back(x); } void dfs(int u){ pre[u] = lowlink[u] = ++dfs_clock; S.push(u); for (int i = 0; i < G[u].size(); i++){ int v = G[u][i]; if (!pre[v]){ dfs(v); lowlink[u] = min(lowlink[u], lowlink[v]); } else if (!sccno[v]) lowlink[u] = min(lowlink[u], pre[v]); } if (lowlink[u] == pre[u]){ scc_cnt += 1; for (;;){ int x = S.top(); S.pop(); sccno[x] = scc_cnt; if (x == u) break; } } } void tarjan(int n){ dfs_clock = scc_cnt = 0; memset(pre, 0, sizeof(pre)); memset(sccno, 0, sizeof(sccno)); memset(lowlink, 0, sizeof(lowlink)); for (int i = 0; i < n; i++) if (!pre[i]) dfs(i); } bool check(int t){ for (int i = 0; i <= 2 * n; i++) G[i].clear(); for (int i = 0; i < n; i++) for (int a = 0; a < 2; a++) for (int j = i + 1; j < n; j++) for (int b = 0; b < 2; b++) if (abs(T[i][a] - T[j][b]) < t) add_edge(i, a ^ 1, j, b ^ 1); tarjan(n * 2); //for (int i = 0; i < n * 2; i++) printf("%d ", sccno[i]); //printf("\n"); for (int i = 0; i < n * 2; i += 2) if (sccno[i] == sccno[i + 1]) return 0; return 1; } int main(){ while(~scanf("%d", &n) && n){ int l = 0, r = 0; for (int i = 0; i < n; i++) for (int j = 0; j < 2; j++){ scanf("%d", &T[i][j]); r = max(r, T[i][j]); } while (l < r){ int m = l + (r - l + 1) / 2; if (check(m)) l = m; else r = m - 1; } printf("%d\n", l); } return 0; }
0 0
- 2SAT+uva1146
- 2-SAT问题的解法(uva1146)
- 【UVA1146】NOW OR LATER 2-SAT问题
- UVA1146 Now or later(2-sat,4级)
- uva1146 - Now or later
- UVA1146 Now or later
- UVA1146 Now or later
- 2-sat
- 【2-SAT】
- 2-SAT
- 2 - sat
- 2-SAT
- 2-SAT
- 2-Sat
- 2-SAT
- 2-sat
- 2-sat
- 2-SAT
- ELF格式文件符号表全解析及readelf命令使用方法
- NSLog的格式
- HTTP协议-教程(二)
- solr 失误的空格 空格是or还是and
- Visual Studio 2010 集成环境下配置OpenGL环境
- 2SAT+uva1146
- APP红海中怎么样找到出路
- PCA降维算法总结以及matlab实现PCA(个人的一点理解)
- Struts2学习笔记--简单的数据校验
- Practical Common Lisp学习笔记(三)常用函数宏备忘
- 如何恢复已删除的 Linux下的 普通文件如何恢复已删除的 Linux下的 普通文件
- 为何要用二进制文件读写
- Spring 注解事务支持
- IO三:按行读取