莫名其妙还找到了另一个铟炔锶烃的OJ : Codeup墓地
25481: swan
时间限制: 1 Sec 内存限制: 128 MB
献花: 86 解决: 13
[献花][花圈][TK题库]题目描述
两头白天鹅生活在一个部分湖面结了冰的湖泊中,湖面的形状为一个长方形,并且被分割成R行C列的小方格,某些方格中结了冰,这样的方格称之为冰格,其余的方格称之为水格。
冬天过去了,湖面上的冰渐渐开始溶解了,每一天与水相邻的冰格就将消融而转化为水格。所谓两个方格相邻是指它们在水平或垂直方向有公共边,两个呈对角的方格是不相邻的,下图给出样例数据的演化过程。
白天鹅只能在水中沿水平或垂直方向游动,写一个程序判断多少天后两只白天鹅才能够相会。
输入
输入文件第一行包含两个用空格隔开的整数R 和C,其中1≤R,C≤1500,接下来的R行每行包含C个字符,描述湖面的初始状态,‘·’表示水格,‘X’表示冰格,‘L’表示一只白天鹅。输出
输出文件仅一行包含一个整数表示两只白天鹅等到相邻那一天所需的天数。样例输入
8 17 ...XXXXXX..XX.XXX ....XXXXXXXXX.XXX ...XXXXXXXXXXXX.. ..XXXXX.LXXXXXX.. .XXXXXX..XXXXXX.. XXXXXXX...XXXX... ..XXXXX...XXX.... ....XXXXX.XXXL...样例输出
2
首先我们可以看到这个动态消融的过程非常铟炔锶烃, 但是仔细想想后我们发现, 每块冰都有一个固定的消融时刻, 而这个时刻可以通过BFS预处理出来.
预处理的方式是将所有水方块入队, 每次取队首结点更新其相邻结点, 更新后新结点入队. 处理直至队列为空.
从一个 $L$ 到另一个 $L$ 中的路径中的结点的融化时间的最大值即为此条路径可用的时间. 而我们的任务实际上就是找到最早可用的路径的可用时刻.
所以这个问题似乎就变成了最短路问题. 不过不同的是平常的最短路是最小化边权/点权的和, 而这次我们要最小化的是路径中边权/点权的最大值. 这种时候不用方, 祭出我们万能的OI三大玄学之一 $SPFA$ 来跑一遍就得出解了OwO
(原题似乎丧病地卡了 std::queue ...给出题人 $2147483647$ 个差评(╯‵□′)╯︵┻━┻然而懒得实现循环队列就开了 $30M$ 个结构体, 每个结构体里两个 int ...(炸内存边缘))
参考代码
1 #include <queue> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <iostream> 6 #include <algorithm> 7 8 const int MAXN=1510; 9 10 struct Point{ 11 int x; 12 int y; 13 Point(int x=0,int y=0){ 14 this->x=x; 15 this->y=y; 16 } 17 }; 18 19 int n; 20 int m; 21 int l=0,r=0; 22 int xa,ya,xb,yb; 23 Point q[30000100]; 24 int dis[MAXN][MAXN]; 25 int melt[MAXN][MAXN]; 26 bool visited[MAXN][MAXN]; 27 28 void BFS(); 29 void gch(char&); 30 void Initialize(); 31 void SPFA(int,int); 32 33 int main(){ 34 Initialize(); 35 BFS(); 36 SPFA(xa,ya); 37 printf("%d ",dis[xb][yb]); 38 return 0; 39 } 40 41 void SPFA(int x,int y){ 42 memset(visited,0,sizeof(visited)); 43 dis[x][y]=0; 44 q[r++]=(Point(x,y)); 45 visited[x][y]=true; 46 while(l<r){ 47 x=q[l].x; 48 y=q[l].y; 49 l++; 50 visited[x][y]=false; 51 if(x>1&&dis[x][y]<dis[x-1][y]&&dis[x-1][y]!=melt[x-1][y]){ 52 dis[x-1][y]=std::max(dis[x][y],melt[x-1][y]); 53 if(!visited[x-1][y]){ 54 visited[x-1][y]=true; 55 q[r++]=(Point(x-1,y)); 56 } 57 } 58 if(x<n&&dis[x][y]<dis[x+1][y]&&dis[x+1][y]!=melt[x+1][y]){ 59 dis[x+1][y]=std::max(dis[x][y],melt[x+1][y]); 60 if(!visited[x+1][y]){ 61 visited[x+1][y]=true; 62 q[r++]=(Point(x+1,y)); 63 } 64 } 65 if(y>1&&dis[x][y]<dis[x][y-1]&&dis[x][y-1]!=melt[x][y-1]){ 66 dis[x][y-1]=std::max(dis[x][y],melt[x][y-1]); 67 if(!visited[x][y-1]){ 68 visited[x][y-1]=true; 69 q[r++]=(Point(x,y-1)); 70 } 71 } 72 if(y<m&&dis[x][y]<dis[x][y+1]&&dis[x][y+1]!=melt[x][y+1]){ 73 dis[x][y+1]=std::max(dis[x][y],melt[x][y+1]); 74 if(!visited[x][y+1]){ 75 visited[x][y+1]=true; 76 q[r++]=(Point(x,y+1)); 77 } 78 } 79 } 80 } 81 82 void BFS(){ 83 memset(visited,0,sizeof(visited)); 84 while(l<r){ 85 int x=q[l].x; 86 int y=q[l].y; 87 ++l; 88 if(x>1&&!visited[x-1][y]&&melt[x][y]+1<melt[x-1][y]){ 89 melt[x-1][y]=melt[x][y]+1; 90 visited[x-1][y]=true; 91 q[r++]=(Point(x-1,y)); 92 } 93 if(x<n&&!visited[x+1][y]&&melt[x][y]+1<melt[x+1][y]){ 94 melt[x+1][y]=melt[x][y]+1; 95 visited[x+1][y]=true; 96 q[r++]=(Point(x+1,y)); 97 } 98 if(y>1&&!visited[x][y-1]&&melt[x][y]+1<melt[x][y-1]){ 99 melt[x][y-1]=melt[x][y]+1; 100 visited[x][y-1]=true; 101 q[r++]=(Point(x,y-1)); 102 } 103 if(y<m&&!visited[x][y+1]&&melt[x][y]+1<melt[x][y+1]){ 104 melt[x][y+1]=melt[x][y]+1; 105 visited[x][y+1]=true; 106 q[r++]=(Point(x,y+1)); 107 } 108 } 109 } 110 111 void Initialize(){ 112 char ch; 113 memset(dis,0x3F,sizeof(dis)); 114 memset(melt,0x3F,sizeof(melt)); 115 scanf("%d%d",&n,&m); 116 for(int i=1;i<=n;i++){ 117 for(int j=1;j<=m;j++){ 118 gch(ch); 119 if(ch=='.'){ 120 q[r++]=(Point(i,j)); 121 melt[i][j]=0; 122 visited[i][j]=true; 123 } 124 else if(ch=='L'){ 125 q[r++]=(Point(i,j)); 126 melt[i][j]=0; 127 visited[i][j]=true; 128 if(xa==0){ 129 xa=i; 130 ya=j; 131 } 132 else{ 133 xb=i; 134 yb=j; 135 } 136 } 137 } 138 } 139 } 140 141 void gch(char& target){ 142 do{ 143 target=getchar(); 144 }while(target!='.'&&target!='X'&&target!='L'); 145 }