B1295 [SCOI2009]最长距离 最短路
就是一道最短路的裸题,直接跑spfa就行了。(spfa死了)
最后在答案处判断是否障碍物太多,然后就直接找最大值就行。
(数据特别水,我错误算法60)
题干:
Description windy有一块矩形土地,被分为 N*M 块 1*1 的小格子。 有的格子含有障碍物。 如果从格子A可以走到格子B,那么两个格子的距离就为两个格子中心的欧几里德距离。 如果从格子A不可以走到格子B,就没有距离。 如果格子X和格子Y有公共边,并且X和Y均不含有障碍物,就可以从X走到Y。 如果windy可以移走T块障碍物,求所有格子间的最大距离。 保证移走T块障碍物以后,至少有一个格子不含有障碍物。 Input 输入文件maxlength.in第一行包含三个整数,N M T。 接下来有N行,每行一个长度为M的字符串,'0'表示空格子,'1'表示该格子含有障碍物。 Output 输出文件maxlength.out包含一个浮点数,保留6位小数。 Sample Input 【输入样例一】 3 3 0 001 001 110 【输入样例二】 4 3 0 001 001 011 000 【输入样例三】 3 3 1 001 001 001 Sample Output 【输出样例一】 1.414214 【输出样例二】 3.605551 【输出样例三】 2.828427 HINT 20%的数据,满足 1 <= N,M <= 30 ; 0 <= T <= 0 。 40%的数据,满足 1 <= N,M <= 30 ; 0 <= T <= 2 。 100%的数据,满足 1 <= N,M <= 30 ; 0 <= T <= 30 。
代码:
#include<iostream> #include<cstdio> #include<cmath> #include<ctime> #include<queue> #include<algorithm> #include<cstring> using namespace std; #define duke(i,a,n) for(int i = a;i <= n;i++) #define lv(i,a,n) for(int i = a;i >= n;i--) #define clean(a) memset(a,0,sizeof(a)) const int INF = 1 << 30; typedef long long ll; typedef double db; template <class T> void read(T &x) { char c; bool op = 0; while(c = getchar(), c < '0' || c > '9') if(c == '-') op = 1; x = c - '0'; while(c = getchar(), c >= '0' && c <= '9') x = x * 10 + c - '0'; if(op) x = -x; } template <class T> void write(T x) { if(x < 0) putchar('-'), x = -x; if(x >= 10) write(x / 10); putchar('0' + x % 10); } int n,m,t; int dx[5] = {0,0,-1,1}; int dy[5] = {1,-1,0,0}; int dis[40][40],a[40][40],mp[40][40]; bool inq[40][40]; bool p[40][40]; char s[40]; db ans = 0; struct node { int x,y; }q[100010]; void getans(int x,int y) { duke(i,x,n) { duke(j,1,m) { if(dis[i][j] <= t && (y - j) * (y - j) + (x - i) * (x - i) > ans) ans = (y - j) * (y - j) + (x - i) * (x - i); } } } void spfa(int x,int y) { int nowx,nowy,t = 1,w = 2,nx,ny; q[1].x = x;q[1].y = y; clean(inq); memset(dis,127,sizeof(dis)); inq[x][y] = 1; dis[x][y] = mp[x][y]; while(t <= w) { nowx = q[t].x;nowy = q[t].y; t++; for(int i = 0;i < 4;i++) { nx = nowx + dx[i]; ny = nowy + dy[i]; if(nx > n || nx < x || ny > m || ny < 1) continue; if(dis[nowx][nowy] + mp[nx][ny] < dis[nx][ny]) { dis[nx][ny] = dis[nowx][nowy] + mp[nx][ny]; if(!inq[nx][ny]) { q[++w].x = nx; q[w].y = ny; inq[nx][ny] = 1; } } } inq[nowx][nowy] = 0; } getans(x,y); } int main() { read(n);read(m);read(t); duke(i,1,n) { scanf("%s",s); duke(j,0,m - 1) mp[i][j + 1] = s[j] - '0'; } duke(i,1,n) { duke(j,1,m) { spfa(i,j); } } printf("%.6lf",sqrt(ans)); return 0; } /* 3 3 0 001 001 110 */
只想找一个不会伤害我的人