zoukankan      html  css  js  c++  java
  • BZOJ 1295: [SCOI2009]最长距离

    题目大意:

    给定一张网格图,求图上删掉T个障碍物之后能联通的两点的最大欧几里德距离是多少。

    题解:

    预处理两点间路径经过的最小障碍物数,判断是否小于T,更新答案。

    代码:

    #include<cstdio>
    #include<algorithm>
    #include<queue>
    #include<cmath>
    #define mp make_pair
    #define pr pair<int,int>
    #define sc second
    using namespace std;
    int n,m,T,cnt,dis[905],vis[905],f[905][905],a[35][35],last[905];
    int dx[4]={0,0,1,-1};
    int dy[4]={1,-1,0,0};
    char s[35];
    struct node{
    	int to,next,val;
    }e[10005];
    priority_queue<pr,vector<pr>,greater<pr> > q;
    int calc(int x,int y){
    	return (x-1)*m+y;
    }
    void Dijkstra(int st){
    	for (int i=1; i<=n*m; i++) dis[i]=1e9,vis[i]=0;
    	dis[st]=0;
    	q.push(mp(0,st));
    	while (!q.empty()){
    		int x=q.top().sc;
    		q.pop();
    		if (vis[x]) continue;
    		vis[x]=1;
    		for (int i=last[x]; i; i=e[i].next){
    			int V=e[i].to;
    			if (dis[V]>dis[x]+e[i].val){
    				dis[V]=dis[x]+e[i].val;
    				q.push(mp(dis[V],V));
    			}
    		}
    	}
    	for (int i=1; i<=n*m; i++) f[st][i]=dis[i];
    }
    void add(int a,int b,int c){
    	e[++cnt].to=b;
    	e[cnt].next=last[a];
    	e[cnt].val=c;
    	last[a]=cnt;
    }
    int main(){
    	scanf("%d%d%d",&n,&m,&T);
    	for (int i=1; i<=n; i++){
    		scanf("%s",s+1);
    		for (int j=1; j<=m; j++)
    			if (s[j]=='1') a[i][j]=1;
    	}
    	for (int i=1; i<=n; i++)
    		for (int j=1; j<=m; j++)
    			for (int k=0; k<4; k++){
    				int fx=i+dx[k],fy=j+dy[k];
    				if (fx<1 || fx>n || fy<1 || fy>m) continue;
    				add(calc(i,j),calc(fx,fy),a[fx][fy]);
    			}
    	for (int i=1; i<=n; i++)
    		for (int j=1; j<=m; j++)
    			Dijkstra(calc(i,j));
    	for (int i=1; i<=n; i++)
    		for (int j=1; j<=m; j++)
    			if (a[i][j]){
    				for (int k=1; k<=n*m; k++)
    					f[calc(i,j)][k]++;
    			}
    	double maxx=0;
    	for (int x1=1; x1<=n; x1++)
    		for (int y1=1; y1<=m; y1++)
    			for (int x2=1; x2<=n; x2++)
    				for (int y2=1; y2<=m; y2++)
    					if (f[calc(x1,y1)][calc(x2,y2)]<=T) maxx=max(maxx,sqrt((double)(x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)));
    	printf("%lf
    ",maxx);
    	return 0;
    }
    

      

  • 相关阅读:
    vue学习笔记(四)---- 品牌管理案例
    vue学习笔记(三)---- vue-resource
    vue学习笔记(二) ---- vue实例的生命周期
    vue学习笔记(一) ---- vue指令(总体大纲)
    vue学习笔记(一)---- vue指令(在vue中使用样式的方式)
    【问题记录】—.NetCore 编译问题
    Docker学习—概念及基本应用
    Consul 学习笔记-服务注册
    认证授权:IdentityServer4
    认证授权:IdentityServer4
  • 原文地址:https://www.cnblogs.com/silenty/p/8744789.html
Copyright © 2011-2022 走看看