P4162 [SCOI2009]最长距离
Posted ljb666
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P4162 [SCOI2009]最长距离相关的知识,希望对你有一定的参考价值。
这道题数据范围比较小,所以方法还是比较暴力的。
思路:
先按每个格子的状态,让所有格子与他周围的格子连一条权值为它连向那个格子的值(0或1)。然后我们n方枚举所有格子跑最短路,最短路即为从起点到终点的最小障碍数。然后我们枚举所有最短路,先看他移除障碍后是否只用了小于等于k次机会,然后求出两点间的距离,取max即可。
代码如下:
#include<bits/stdc++.h> using namespace std; const int maxn=1e6+7; struct node int nxt,to,val; edge[maxn*3]; int head[maxn],cnt; int num[550][550]; int val[550][550]; char s[550][550]; int n,m,t; void add(int x,int y,int v) edge[++cnt].nxt=head[x]; edge[cnt].to=y; edge[cnt].val=v; head[x]=cnt; priority_queue<pair<int ,int> >q; double dist(int x,int y,int xx,int yy) return (double)sqrt((x-xx)*(x-xx)*1.0+(y-yy)*(y-yy)*1.0); double ans; bool vis[maxn]; int dis[maxn]; void dijkstra(int x) memset(dis,88,sizeof(dis)); memset(vis,0,sizeof(vis)); dis[x]=0; q.push(make_pair(0,x)); while(q.size()) int u=q.top().second; q.pop(); if(vis[u]) continue; vis[u]=true; for(int i=head[u];i;i=edge[i].nxt) int v=edge[i].to; if(dis[v]>dis[u]+edge[i].val) dis[v]=dis[u]+edge[i].val; q.push(make_pair(-dis[v],v)); int main() scanf("%d%d%d",&n,&m,&t); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) cin>>s[i][j]; num[i][j]=(i-1)*m+j; if(s[i][j]==‘1‘) val[i][j]=1; /* for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) printf("%d ",num[i][j]); printf("\n"); */ for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(i>1) add(num[i][j],num[i-1][j],val[i-1][j]); if(i<n) add(num[i][j],num[i+1][j],val[i+1][j]); if(j>1) add(num[i][j],num[i][j-1],val[i][j-1]); if(j<m) add(num[i][j],num[i][j+1],val[i][j+1]); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) dijkstra(num[i][j]); for(int x=1;x<=n;x++) for(int y=1;y<=m;y++) if(dis[num[x][y]]+val[i][j]<=t) ans=max(ans,dist(i,j,x,y)); printf("%.6lf\n",ans); return 0;
以上是关于P4162 [SCOI2009]最长距离的主要内容,如果未能解决你的问题,请参考以下文章