这道题的难点应该就是想到这是一道二分图匹配
想到这点以后,就是建图了
//by baobaopangzi88 #include <iostream> #include <sstream> #include <ios> #include <iomanip> #include <functional> #include <algorithm> #include <vector> #include <string> #include <list> #include <queue> #include <deque> #include <stack> #include <set> #include <map> #include <cstdio> #include <cstdlib> #include <cmath> #include <cstring> #include <climits> #include <cctype> #define INF 0x3f3f3f3f #define MP(X,Y) make_pair(X,Y) #define PB(X) push_back(X) #define REP(X,N) for(int X=0;X<N;X++) #define REP2(X,L,R) for(int X=L;X<=R;X++) #define DEP(X,R,L) for(int X=R;X>=L;X--) #define CLR(A,X) memset(A,X,sizeof(A)) #define IT iterator #define PI 3.14159265358979323846 #define _ ios_base::sync_with_stdio(0);cin.tie(0); #define X first #define Y second #define MAX_V 10101 #define maxn 13 using namespace std; typedef long long ll; typedef pair<int,int>PII; int n,m,V; char M[maxn][maxn]; vector<int> G[30000]; vector<int >dx,dy,px,py; int D[maxn][maxn][maxn][maxn]; int Dx[4]={-1,1,0,0},Dy[4]={0,0,-1,1}; int match[30000]; bool used[30000]; void add_edge(int from,int to){ G[from].PB(to); G[to].PB(from); } bool dfs(int v){ used[v]=1; for(int i=0;i<G[v].size();++i){ int to=G[v][i],w=match[to]; if(w<0 || !used[w] && dfs(w)){ match[v]=to; match[to]=v; return true; } } return false; } void bfs(int x,int y,int D[maxn][maxn]){ D[x][y]=0; queue<int >qx,qy; qx.push(x); qy.push(y); while(!qx.empty()){ x=qx.front();qx.pop(); y=qy.front();qy.pop(); for(int i=0;i<4;++i){ int nx=x+Dx[i],ny=y+Dy[i]; if(nx>=0 && nx<n && ny>=0 && ny<m && M[nx][ny]==‘.‘ && D[nx][ny]<0){ D[nx][ny]=D[x][y]+1; qx.push(nx); qy.push(ny); } } } } int solve(){ dx.clear();dy.clear(); px.clear();py.clear(); memset(D,-1,sizeof(D)); for(int i=0;i<n;++i) for(int j=0;j<m;++j){ if(M[i][j]==‘D‘){ dx.PB(i); dy.PB(j); bfs(i,j,D[i][j]); } else if(M[i][j]==‘.‘){ px.PB(i); py.PB(j); } } //build_graph int temp=n*m;//时间的最大数 int d=dx.size(),p=px.size(); V=n*m*d+p; for(int v=0;v<V;++v) G[v].clear(); for(int i=0;i<d;++i) for(int j=0;j<p;++j) for(int t=0;t<temp;++t){ if(D[dx[i]][dy[i]][px[j]][py[j]]>0 && D[dx[i]][dy[i]][px[j]][py[j]]<=t+1){ add_edge(t*d+i,temp*d+j); } } if(p==0) return 0; int res=0; memset(match,-1,sizeof(match)); for(int t=0;t<temp;++t){ for(int v=t*d;v<(t+1)*d;++v){ if(match[v]<0){ memset(used,0,sizeof(used)); if(dfs(v)){ res++; } } } if(res==p) return t+1; } return -1; } int main() { int T; cin>>T; while(T--){ cin>>n>>m; for(int i=0;i<n;++i) cin>>M[i]; int temp=solve(); if(temp<0) cout<<"impossible"<<endl; else cout<<temp<<endl; } return 0; }
时间: 2024-10-11 22:14:06