题目链接:http://acm.fzu.edu.cn/problem.php?pid=2150
题意:
给定一个平面图 . 为空地(不着火) # 为草
开始可以选1-2个草堆点燃,每隔一秒会把上下左右的草引燃(开始时间为0秒)
问把所有草烧光的最少时间
给定的图中必有草
思路:
纯暴力的话复杂度是 n^8 TLE
我们可以先处理出2个数组
d数组 表示任意点间距离
go[i][j] 表示 在 (i ,j) 所在的联通块 中里 (i ,j) 最远的草的距离
预处理时间为n^4
对于题目中的草其实可以分为
联通块>2 (显然是烧不完的 , ans = -1)
联通块 == 2 ( 每个联通块都要一个火把点燃, 而每个联通块最长时间则是 go[ 该联通块的点 ] , 取个两联通块需要的最长时间即可 复杂度为n^2)
联通块 == 1 ( 我们设 a, b为起点 ,则对于图中的草c,被点燃的时间就是 min(d[a][c], d[b][c]) ,则暴力一下所有草就得到 ab为起点的时间,暴力一下ab就得到正解
复杂度为n^6
#include<iostream>
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<algorithm>
#include<queue>
#include<set>
using namespace std;
#define N 12
int f[1000];
int find(int x){return x==f[x]?x:f[x] = find(f[x]);}
int idx(int x,int y){return x*10+y;}
void Union(int x,int y){
int fx = find(x), fy = find(y);
if(fx == fy)return ;
fx<fy ? f[fy] = fx: f[fx] = fy;
}
int map[N][N], n, m;
struct node{
int x, y;
};
int step[4][2]={0,1,1,0,0,-1,-1,0};
bool inmap(node x){return 0<=x.x && x.x<n && 0<=x.y &&x .y<m;}
int d[N][N][N][N];//任意点距离
int BFS(node a){
d[a.x][a.y][a.x][a.y] = 0;
queue<node>q;
q.push(a);
int ans = 0;
while(!q.empty()){
node u = q.front(); q.pop();
for(int i = 0;i < 4; i++){
node v = u; v.x += step[i][0]; v.y += step[i][1];
if(!inmap(v) || map[v.x][v.y] == 0 || d[a.x][a.y][v.x][v.y] != -1)continue;
d[a.x][a.y][v.x][v.y] = d[a.x][a.y][u.x][u.y]+1;
ans = max(ans, d[a.x][a.y][v.x][v.y]);
q.push(v);
}
}
return ans;
}
set<int>myset;//所有祖先
set<int>::iterator p;
int go[N][N]; //go[i][j]表示在(i,j)联通块中离(i,j)最远点距离
int main()
{
int T,Cas = 1;
scanf("%d",&T);
int i, j, k, l;
while(T--){
myset.clear();
memset(d, -1, sizeof(d));
memset(go, -1, sizeof(go));
memset(map, 0, sizeof(map));
scanf("%d %d",&n,&m);
for(i=0;i<N*N;i++)f[i] = i;
int size = 0;
for(i=0;i<n;i++)
{ char s[20];scanf("%s",s);
for(j=0;j<m;j++)
{
map[i][j] = s[j] == '#';
if(map[i][j])
{
size++;
for(k = 0;k<4;k++)
{
int x=i+step[k][0], y =j+step[k][1];
if(x<0 || x>=n || y<0 || y>=m || map[x][y] == 0)continue;
Union(idx(i,j), idx(x,y));
}
}
}
}
if(size<=2){printf("Case %d: 0\n",Cas++);continue;}
for(i= 0;i<n;i++)
for(j=0;j<m;j++)if(map[i][j])find(idx(i,j));
for(i= 0;i<n;i++)for(j=0;j<m;j++)if(map[i][j])
myset.insert(f[idx(i,j)]);
if(myset.size() >= 3){printf("Case %d: -1\n",Cas++);continue;}
bool hehe = myset.size() == 2;
int ans = 100000;
for(i=0;i<n;i++)
for(j=0;j<m;j++)if(map[i][j])
{
node a; a.x =i, a.y =j;
go[i][j] = BFS(a);
}
if(hehe)
{
p = myset.begin();
int f1 = *p, a1=1000000;
p++;
int f2 = *p, a2=1000000;
for(i =0;i<n;i++)
for(j=0;j<m;j++)if(map[i][j] && f[idx(i,j)] == f1)a1 = min(a1, go[i][j]);
for(i =0;i<n;i++)
for(j=0;j<m;j++)if(map[i][j] && f[idx(i,j)] == f2)a2 = min(a2, go[i][j]);
ans = max(a1,a2);
}
else
{
for(i = 0; i < n; i++)
for(j = 0; j < m; j++)if(map[i][j])
for(k = 0; k < n; k++)
for(l = 0; l < m; l++)if(map[k][l])
{
int tmp = 0;
for(int z = 0; z < n; z++)
for(int y = 0; y<m;y++)if(map[z][y])
tmp = max(tmp, min(d[i][j][z][y],d[k][l][z][y]));
ans = min(ans, tmp);
}
}
printf("Case %d: %d\n", Cas++, ans);
}
return 0;
}
/*
99
3 3
.#.
###
.#.
3 3
.#.
#.#
.#.
3 3
...
#.#
...
3 3
###
..#
#.#
3 3
###
...
#.#
1 1
#
1 10
.#######.#
10 10
.#.#.#.#.#
.#.#.#.#.#
.#.#.#.#.#
.#.#.#.#.#
.#.#.#.#.#
.#.#.#.#.#
.#.#.#.#.#
.#.#.#.#.#
.#.#.#.#.#
.#.#.#.#.#
10 10
####.#####
####.#####
####.#####
####.#####
####.#####
####.#####
####.#####
####.#####
####.#####
####.#####
10 10
##########
##########
##########
##########
##########
##########
##########
##########
##########
##########
9 9
#########
#########
#########
#########
#########
#########
#########
#########
#########
3 3
###
###
###
4 4
####
####
####
####
5 5
#####
#####
#####
#####
#####
5 5
##.##
##.##
##.##
##.##
##.##
5 5
##.##
##..#
#.###
##.#.
##.##
6 7
#.#.#.#
#.#.#.#
###.#.#
#####..
###..##
#######
6 8
#.#.#.##
#.#.#.#.
###.#.##
#####..#
###..###
#######.
7 8
#.#.#.##
#.#.#.#.
###.#.##
#####..#
###..###
######..
......##
7 8
#.#.#.##
#.#.#.#.
###.#.##
#####..#
###...##
######..
......##
7 8
#.#.#.##
#.#.#.#.
###.####
#####..#
###...##
######..
......##
3 3
.#.
...
#.#
8 8
#.#.#.##
#.#.#.#.
###.####
#####..#
###...##
######..
......##
#######.
8 8
########
......#.
########
.#......
#.######
#.######
###.####
########
9 1
.
#
#
.
#
#
#
#
#
9 1
#
#
#
#
#
#
#
#
#
10 10
####.#####
####.#####
####.#####
##########
....#.....
####.#####
####.#####
####.#####
##########
####.#####
*/