SRM464 div1 medium
二部探索+2SATらしい。
#include <vector> #include <cstdio> #include <cstring> using namespace std; class ColorfulDecoration { public: int n; int len; int dist[110][110]; int G[110][110]; int ABS(int n) { return (n<0)?-n:n; } bool check() { memset(G,0,sizeof(G)); for(int i=0;i<2*n;i++) for(int j=0;j<2*n;j++) if(i%n!=j%n && dist[i][j]<len) { int ii=(i<n)?i+n:i-n; int jj=(j<n)?j+n:j-n; G[i][jj]=1; } for(int i=0;i<2*n;i++) G[i][i]=1; for(int k=0;k<2*n;k++) for(int i=0;i<2*n;i++) for(int j=0;j<2*n;j++) if(G[i][k]==1 && G[k][j]==1) G[i][j]=1; for(int i=0;i<n;i++) if(G[i][i+n] && G[i+n][i]) return false; return true; } int getMaximum(vector <int> xa, vector <int> ya, vector <int> xb, vector <int> yb) { n=xa.size(); for(int i=0;i<2*n;i++) for(int j=0;j<2*n;j++) { int x1=(i<n)?xa[i]:xb[i-n]; int y1=(i<n)?ya[i]:yb[i-n]; int x2=(j<n)?xa[j]:xb[j-n]; int y2=(j<n)?ya[j]:yb[j-n]; dist[i][j]=max(ABS(x1-x2),ABS(y1-y2)); //printf("dist[%d][%d]=%d\n",i,j,dist[i][j]); } int ceil=1000000000,bottom=0; while(5<ceil-bottom) { len=(ceil+bottom)/2; if(check()) bottom=len; else ceil=len; } for(len=ceil;bottom<=len;len--) { if(check()) return len; } return 0; } };