まさかの2-SAT。
論理式にして強連結成分分解? 小さいし、無向だし、律儀にやる必要はなかった。
あまり描く機会がなかったから、気付いても描けなかった。復習しておこう。
const int N = 51 * 2; bool g[N][N]; int rev(int i, int n){ return (i < n) ? i+n : i-n; } void build_graph(vector <int> xa, vector <int> ya, vector <int> xb, vector <int> yb, int lim) { const int n = xa.size(); const int node = n * 2; fill( &g[0][0], &g[N-1][N], false ); for(int i=0; i<node; ++i){ for(int j=0; j<node; ++j){ if( i == j )continue; 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]; g[i][ rev(j, n) ] = abs( x1 - x2 ) < lim && abs( y1 - y2 ) < lim; } } return ; } void scc(int size) { for(int k=0; k<size; ++k){ for(int i=0; i<size; ++i){ for(int j=0; j<size; ++j){ g[i][j] |= g[i][k] & g[k][j]; } } } return ; } class ColorfulDecoration { public: int getMaximum(vector <int> xa, vector <int> ya, vector <int> xb, vector <int> yb) { const int n = xa.size(); const int node = n * 2; int s, b, c; s = 0; b = 1000100000; while( s + 1 < b ){ c = (s + b) / 2; build_graph(xa, ya, xb, yb, c); scc(node); bool flg = true; for(int i=0; i<n; ++i){ if( g[i][i + n] && g[i + n][i] )flg = false; } if( flg )s = c; else b = c; } return s; } };
0 件のコメント :
コメントを投稿