#include <iostream> #include <algorithm> #include <vector> #include <cmath> #include <cstdio> #include <queue> using namespace std; const int N = 100 + 3; struct Edge{ double cost; int dst; Edge(){} Edge(int d, double c) : cost(c), dst(d) {} }; vector<Edge> g[N]; const int src = N-1; const int dst = N-2; bool f[N][N]; int path[N]; const double eps = 1e-11; inline bool eq(double a, double b) { return fabs(a - b) < eps; } inline bool lessThan(double a, double b) { return !eq(a, b) && a < b; } inline bool greaterThan(double a, double b) { return !eq(a, b) && a < b; } int bfs(int lim) { static int p[N]; static bool vis[N]; queue<int> q; fill( vis, vis + N, false ); fill( p, p + N, -1 ); vis[src] = true; for(q.push(src); q.size(); q.pop()){ int n = q.front(); for(int i=0; i<g[n].size(); ++i){ int m = g[n][i].dst; if( vis[ m ] ) continue; if( !f[ n ][ m ] ) continue; if( lessThan(lim, g[n][i].cost) ) continue; vis[ m ] = true; q.push(m); p[ m ] = n; } } if( !vis[dst] )return 0; int size = 0; for(int i=dst; i!=-1; i=p[i]){ path[ size++ ] = i; } reverse( path, path + size ); return size; } int flow(int lim) { static bool tmp[N][N]; copy( &f[0][0], &f[N-1][N], &tmp[0][0] ); int sum = 0; for(int size; size = bfs(lim); ++sum){ for(int i=0; i+1<size; ++i){ f[ path[i] ][ path[i+1] ] = false; f[ path[i+1] ][ path[i] ] = true; } } copy( &tmp[0][0], &tmp[N-1][N], &f[0][0] ); return sum; } bool make_graph(int size, int m) { pair<double, double> p[size]; char color[size]; fill( g, g + N, vector<Edge>() ); for(int i=0; i<size; ++i){ string s; cin >> p[i].first >> p[i].second >> s; color[i] = s[0]; } if( count(color, color + size, 'r') < m )return false; if( count(color, color + size, 'b') < m )return false; for(int i=0; i<size; ++i){ if( color[i] == 'b' )continue; for(int j=0; j<size; ++j){ if( color[j] == 'r' )continue; double a = p[i].first - p[j].first; double b = p[i].second - p[j].second; double c = sqrt(a * a + b * b); f[i][j] = true; f[j][i] = false; g[i].push_back( Edge(j, c) ); g[j].push_back( Edge(i, c) ); } } for(int i=0; i<size; ++i){ if( color[i] == 'r' ){ f[src][i] = true; g[src].push_back( Edge(i, 0) ); } } for(int i=0; i<size; ++i){ if( color[i] == 'b' ){ f[i][dst] = true; g[i].push_back( Edge(dst, 0) ); } } return true; } int main(void) { int tc; cin >> tc; while( tc-- ){ int n, m; cin >> n >> m; if( !make_graph(n, m) ){ cout << "Impossible" << endl; continue; } int s = 1, b = 2000 * 2; while( s + 1 < b ){ int c = (s + b) / 2; int f = flow(c); //cout << c << ' ' << (m <= f ? "T" : "F") << endl; if(m <= f)b = c; else s = c; } double mx = 0; for(int i=0; i<N; ++i){ for(int j=0; j<g[i].size(); ++j){ if( lessThan(b, g[i][j].cost) )continue; mx = max(mx, g[i][j].cost); } } cout << (int)ceil(mx) << endl; } return 0; }
5/16/2011
UVa11262
登録:
コメントの投稿
(
Atom
)
0 件のコメント :
コメントを投稿