X集合 :二元组(时间,门)
Y集合 : 人
只需要按时间递增去找增广路 ,时间递增也就是点从0 ,1 ,2 , , , Td-1。 直到最大匹配数恰好等于人的个数也就是p。则结束。
#define X first
#define Y second
const int maxn = 13 ;
vector< pair<int,int> > door , man ;
int dist[maxn][maxn][maxn][maxn] ;
char str[18][18] ;
int d[4][2] = {{1,0} , {-1,0} , {0,1} , {0 ,-1}} ;
int n , m ;
vector<int> g[21000] ;
int match[maxn * maxn] ;
bool vis[maxn * maxn] ;
int Yset ;
inline int cango(int x , int y){
return 1 <= x && x <= n && 1 <= y && y <= m ;
}
void bfs(pair<int ,int> s){
queue< pair<int ,int> > que ;
que.push(s) ;
dist[s.X][s.Y][s.X][s.Y] = 0 ;
while(! que.empty()){
pair<int ,int> now = que.front() ; que.pop() ;
for(int i = 0 ; i < 4 ; i++){
int x = now.X + d[i][0] ;
int y = now.Y + d[i][1] ;
if(cango(x , y) && str[x][y] == '.' && dist[s.X][s.Y][x][y] == -1){
dist[s.X][s.Y][x][y] = dist[s.X][s.Y][now.X][now.Y] + 1 ;
que.push(make_pair(x,y)) ;
}
}
}
}
int dfs(int u){
for(vector<int>::iterator it = g[u].begin() ; it != g[u].end() ; it++){
if(vis[*it]) continue ;
vis[*it] = 1 ;
if(match[*it] == -1 || dfs(match[*it])){
match[*it] = u ;
return 1 ;
}
}
return 0 ;
}
void Answer(){
int T = n * m ;
int d = door.size() ;
int p = man.size() ;
if(p == 0){ puts("0") ; return ;}
int i , j , k , s , u , sum = 0 ;
for(i = 0 ; i <= d*T ; i++) g[i].clear() ;
for(i = 0 ; i < d ; i++){
for(j = 0 ; j < p ; j++){
if((s = dist[door[i].X][door[i].Y][man[j].X][man[j].Y]) >= 0){
for(k = s ; k <= T ; k++)
g[(k-1)*d + i].push_back(T*d + j) ;
}
}
}
memset(match , -1 , sizeof(match)) ;
Yset = p
for(u = 0 ; u < T*d ; u++){
memset(vis , 0 , sizeof(vis)) ;
if(dfs(u)){
if(++sum == p){
printf("%d\n" , u/d + 1) ;
return ;
}
}
}
puts("impossible") ;
}
int main(){
int i , j , t ;
cin>>t ;
while(t--){
cin>>n>>m ;
for(i = 1 ; i <= n ; i++) scanf("%s" ,str[i]+1) ;
memset(dist , -1 , sizeof(dist)) ;
door.clear() ; man.clear() ;
for(i = 1 ; i <= n ; i++){
for(j = 1 ; j <= m ; j++){
if(str[i][j] == 'D'){
door.push_back(make_pair(i,j)) ;
bfs(make_pair(i,j)) ;
}
else if(str[i][j] == '.')
man.push_back(make_pair(i,j)) ;
}
}
Answer() ;
}
return 0 ;
}