UVa 1146

题目链接:https://onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=545&page=show_problem&problem=3587

要求相隔最短的着陆时间的最大值,二分答案,如果相邻两个飞机之间着陆时间小于 (P),因为只有早着陆和晚着陆,那么限制两个条件不能同时满足,就转化为了 (2-SAT)

注意 (2-SAT) 的编号问题,为了方便,从 (0) 编号,每个点对应的点分别是 (i*2)(i*2+1)

如果边太多,用 (vector) 或者邻接表,不然如果边开少了会 (RE)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

const int maxn = 2020;

int n, m; 
int T[maxn][2];

vector<int> G[maxn*2];

int S[maxn*2], c;
bool mark[maxn*2];

bool dfs(int u){
	if(mark[u^1]) return false;
	if(mark[u]) return true;
	
	mark[u] = true;
	S[c++] = u;
	for(int i = 0 ; i < G[u].size() ; ++i){
		if(!dfs(G[u][i])) return false;
	}
	return true;
}

bool solve(){
	for(int i = 0 ; i < 2 * n ; 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;
}

bool check(int x){
	for(int i = 0 ; i < n * 2 ; ++i) G[i].clear();
	memset(mark, 0, sizeof(mark));
	memset(S, 0, sizeof(S));
	c = 0;
	
	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]) < x){
				if(a == 0 && b == 0){
					G[i*2].push_back(j*2+1);
					G[j*2].push_back(i*2+1);
				} else if(a == 0 && b == 1){
					G[i*2].push_back(j*2);
					G[j*2+1].push_back(i*2+1);
				} else if(a == 1 && b == 0){
					G[i*2+1].push_back(j*2+1);
					G[j*2].push_back(i*2);
				} else{
					G[i*2+1].push_back(j*2);
					G[j*2+1].push_back(i*2);
				}
			}
		}
	
	return solve();
}

ll read(){ ll s = 0, f = 1; char ch = getchar(); while(ch < '0' || ch > '9'){ if(ch == '-') f = -1; ch = getchar(); } while(ch >= '0' && ch <= '9'){ s = s * 10 + ch - '0'; ch = getchar(); } return s * f; }

int main(){
	while(scanf("%d", &n) == 1 && n){
		int L = 0, R = 0;
		for(int i = 0 ; i < n ; ++i){
			scanf("%d%d", &T[i][0], &T[i][1]);
			R = max(R, max(T[i][0], T[i][1]));
		}
		
		int ans;
		while(L <= R){
			int mid = (L + R) >> 1;
			if(check(mid)){
				ans = mid;
				L = mid + 1;
			} else{
				R = mid - 1;
			}
		}
		
		printf("%d
", ans);
	}
	return 0;
}
原文地址:https://www.cnblogs.com/tuchen/p/15025287.html