標籤:style blog color os io for
白書上的例題。
每種航班可以選擇兩種時間降落,如果想任意航班降落時間差的最小值最大,應該如何安排?
二分時間,如果兩個時間只差小於當前枚舉的時間,說明這條邊不可選,可以根據2sat的方法構圖。
然後判斷安排方案是否合法即可。
召喚代碼君:
#include <iostream>#include <cstdio>#include <cstring>#define maxn 5555#define maxm 26666666using namespace std;int to[maxm],next[maxm],first[maxn],edge;int t[maxn],Q[maxn],top=0;int n,m;bool mark[maxn];int abs(int x){ return x>=0?x:-x;}void addedge(int U,int V){ edge++; to[edge]=V,next[edge]=first[U],first[U]=edge;}bool dfs(int cur){ if (mark[cur^1]) return false; if (mark[cur]) return true; Q[++top]=cur,mark[cur]=true; for (int i=first[cur]; i!=-1; i=next[i]) if (!dfs(to[i])) return false; return true;}bool check(int x){ edge=-1; for (int i=2; i<=n+n+1; i++) first[i]=-1,mark[i]=false; for (int i=2; i<=n+n+1; i++) for (int j=(i|1)+1; j<=n+n+1; j++) if (abs(t[i]-t[j])<x) addedge(i,j^1),addedge(j,i^1); for (int i=2; i<=n+n; i+=2) { if (mark[i] || mark[i+1]) continue; top=0; if (!dfs(i)) { while (top) mark[Q[top--]]=false; if (!dfs(i+1)) return false; } } return true;}int main(){ while (scanf("%d",&n)!=EOF) { for (int i=1; i<=n; i++) scanf("%d%d",&t[i+i],&t[i+i+1]); int l=0,r=10000000,mid; while (l<r) { mid=(l+r+1)>>1; if (check(mid)) l=mid; else r=mid-1; } printf("%d\n",l); } return 0;}