题意:
有一个X*Y的房间,每块区域只能是墙 ‘X’ , 空地’.’ 或门 ’D‘。最外层的区域一定是门或者墙壁,而内部区域一定没有门,假设房间发生火情,每一个空地都站着一个人,而外侧的每个门每一秒只能出一个人,每个空地每一秒也只能站一个人,一个人其逃跑路线只能是向上、向下、向左、向右,问所有人都能顺利逃脱的最小时间,如果不能使所有人都顺利逃脱输出impossible
思路:
但是,上面会TLE
为什么会T掉,还是个迷555
代码实现:
#include<iostream>
#include<stdio.h>
#include<vector>
#include<string.h>
#include<queue>
using namespace std;
const int dx[4] = { -1, 0, 0, 1 }, dy[4] = { 0, -1, 1, 0 };
int X, Y;
#define MAX_X 14
#define MAX_Y 14
#define MAX_V 7005
int V;
vector<int>G[MAX_V];
int match[MAX_V];
bool used[MAX_V];
void add_edge(int u, int v)
{
G[u].push_back(v);
G[v].push_back(u);
}
bool dfs(int v)
{
used[v] = true;
for (int i = 0; i<G[v].size(); i++)
{
int u = G[v][i], w = match[u];
if (w<0 || !used[w] && dfs(w))
{
match[v] = u;
match[u] = v;
return true;
}
}
return false;
}
char field[MAX_X][MAX_Y];
vector<int>dX, dY;
vector<int>pX, pY;
int dist[MAX_X][MAX_Y][MAX_X][MAX_Y];
void bfs(int x, int y, int d[MAX_X][MAX_Y])
{
queue<int>qx, qy;
d[x][y] = 0;
qx.push(x);
qy.push(y);
while (!qx.empty())
{
x = qx.front(); qx.pop();
y = qy.front(); qy.pop();
for (int k = 0; k<4; k++)
{
int x2 = x + dx[k], y2 = y + dy[k];
if (0 <= x2&&x2<X && 0 <= y2&&y2<Y&&field[x2][y2] == '.'&&d[x2][y2]<0)
{
d[x2][y2] = d[x][y] + 1;
qx.push(x2);
qy.push(y2);
}
}
}
}
void solve()
{
int n = X*Y;
dX.clear(); dY.clear();
pX.clear(); pY.clear();
memset(dist, -1, sizeof(dist));
for (int x = 0; x<X; x++)
{
for (int y = 0; y<Y; y++)
{
if (field[x][y] == 'D')
{
dX.push_back(x);
dY.push_back(y);
bfs(x, y, dist[x][y]);
}
else if (field[x][y] == '.')
{
pX.push_back(x);
pY.push_back(y);
}
}
}
int d = dX.size(), p = pX.size();
for (int i = 0; i<d; i++)
{
for (int j = 0; j<p; j++)
{
if (dist[dX[i]][dY[i]][pX[j]][pY[j]] >= 0)
for (int k = dist[dX[i]][dY[i]][pX[j]][pY[j]]; k <= n; k++)
{
add_edge((k - 1)*d + i, n*d + j);
}
}
}
if (p == 0)
{
puts("0");
return;
}
int num = 0;
memset(match, -1, sizeof(match));
for (int v = 0; v<n*d; v++)
{
memset(used, 0, sizeof(used));
if (dfs(v))
{
if (++num == p)
{
printf("%d\n", v / d + 1);
return;
}
}
}
printf("impossible\n");
return;
}
int main()
{
//freopen("c:in.txt", "r", stdin);
int T;
cin >> T;
while (T--)
{
cin >> X >> Y;
getchar();
for (int x = 0; x<X; x++)
{
for (int y = 0; y<Y; y++)
{
scanf("%c", &field[x][y]);
}
getchar();
}
solve();
for(int i=0;i<20001;i++)
G[i].clear();
}
}
TLE的代码
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<vector>
#include<queue>
using namespace std;
typedef long long ll;
const int maxn = 2e5 + 5;
int dx[4] = {-1,0,0,1};
int dy[4] = {0,-1,1,0};
int X,Y;
char field[20][20];
vector<int> dX,dY; //门的坐标
vector<int> pX,pY; //人的坐标
int dist[20][20][20][20]; //最近距离
int V;
vector<int>G[maxn];
int match[maxn];
int vis[maxn];
bool dfs(int x){
vis[x] = 1;
for(int i = 0;i < G[x].size();i++){
if(match[G[x][i]] == -1||(!vis[match[G[x][i]]]&&dfs(match[G[x][i]]))){
match[G[x][i]] = x;
//match[x] = G[x][i];
return true;
}
}
return false;
}
void C(){
int d = dX.size(); int p = pX.size();
for(int i = 0;i <= X * Y * d + p;i++) G[i].clear();
for(int i = 0;i < d;i++){
for(int j = 0;j < p;j++){
if(dist[dX[i]][dY[i]][pX[j]][pY[j]] >= 0){
for(int k = dist[dX[i]][dY[i]][pX[j]][pY[j]];k <= X*Y;k++){
int u = (k - 1) * d + i;
int v = X * Y * d + j;
G[u].push_back(v);//无向图??
// G[v].push_back(u);
}
}
}
}
memset(match,-1,sizeof(match));
int num = 0;
if(p == 0){
printf("0\n");
return ;
}
for(int i = 0;i < X * Y * d;i++){
memset(vis,0,sizeof(vis));
if(dfs(i)){
if(++num == p){
printf("%d\n",i / d + 1);
return ;
}
}
}
printf("impossible\n");
}
void bfs(int x,int y,int d[20][20]){
queue<int> qx,qy;
while(!qx.empty()) qx.pop();
while(!qy.empty()) qy.pop();
d[x][y] = 0;
qx.push(x);
qy.push(y);
while(!qx.empty()){
x = qx.front(); qx.pop();
y = qy.front(); qy.pop();
for(int k = 0;k < 4;k++){
int x2 = x + dx[k];
int y2 = y + dy[k];
if(x2>=0&&x2<X&&y2>=0&&y2<Y&&field[x2][y2]=='.'&&d[x2][y2]<0){
d[x2][y2] = d[x][y] + 1;
qx.push(x2);
qy.push(y2);
}
}
}
}
void solve(){
int n = X * Y;
for(int x = 0;x < X;x++){
for(int y = 0;y < Y;y++){
if(field[x][y] == 'D'){
dX.push_back(x);
dY.push_back(y);
bfs(x,y,dist[x][y]);
}
else if(field[x][y] == '.'){
pX.push_back(x);
pY.push_back(y);
}
}
}
C();
/*int l = -1,r = n + 1; int ans = n + 1;
while(l <= r){
int mid = (l + r) / 2;
if(C(mid)){
r = mid - 1;
ans = mid;
}
else l = mid + 1;
}
if(ans > n) printf("impossible\n");
else printf("%d\n",ans);*/
}
int main(){
int t;
scanf("%d",&t);
while(t--){
scanf("%d%d",&X,&Y);
for(int i = 0;i < X;i++){
scanf(" %s",field[i]);
}
memset(dist,-1,sizeof(dist));
dX.clear(); dY.clear();
pX.clear(); pY.clear();
solve();
}
return 0;
}