题目链接: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 ####.##### ####.##### ####.##### ########## ....#..... ####.##### ####.##### ####.##### ########## ####.##### */