zoukankan      html  css  js  c++  java
  • 题解 [BZOJ1295][SCOI2009] 最长距离

    题面

    解析

    (n)只有(30)可以直接枚举每个矩形,

    判断他们的左上角到右下角或右上角到左上角的最短路是否小于(T).

    最短路可以用(dijkstra).

    一开始想用(DP)写最短路后来才知道思路有问题(因为最短路的方案可能不在矩形中).

    code:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <queue>
    #define fre(x) freopen(x".in","r",stdin),freopen(x".out","w",stdout)
    using namespace std;
    
    inline int read(){
    	int sum=0,f=1;char ch=getchar();
    	while(ch>'9' || ch<'0'){if(ch=='-')f=-1;ch=getchar();}
    	while(ch>='0' && ch<='9'){sum=sum*10+ch-'0';ch=getchar();}
    	return f*sum;
    }
    
    const int N=35;
    struct edge{int to,next,w;}e[N*N*4];
    int n,m,T,a[N][N];
    int f[N*N][N*N],id[N][N],tot=0;
    int ans=0,v[N*N];
    int head[N*N],cnt=0;
    int dx[4]={0,0,1,-1},dy[4]={1,-1,0,0};
    priority_queue < pair<int,int> > que;
    
    inline void add(int x,int y,int w){
    	e[++cnt]=(edge){head[x],y,w};head[x]=cnt;
    }
    
    inline void dji(int s){
    	memset(v,0,sizeof(v));
    	que.push(make_pair(f[s][s],s));
    	while(!que.empty()){
    		int x=que.top().second;que.pop();
    		if(v[x]) continue;v[x]=1;
    		for(int i=head[x];i;i=e[i].to){
    			int k=e[i].next;
    			if(f[s][k]>f[s][x]+e[i].w){
    				f[s][k]=f[s][x]+e[i].w;
    				que.push(make_pair(-f[s][k],k));
    			}
    		}
    	}
    }
    
    int main(){
    	n=read();m=read();T=read();
    	for(int i=1;i<=n;i++){
    		char c[N];cin>>c;
    		for(int j=0;j<m;j++) a[i][j+1]=c[j]-'0';
    	}
    	memset(f,0x3f,sizeof(f));
    	for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) id[i][j]=++tot;
    	for(int i=1;i<=n;i++)
    		for(int j=1;j<=m;j++)
    			for(int k=0;k<4;k++){
    				int x=i+dx[k],y=j+dy[k];
    				if(!x||x>n||!y||y>m) continue;
    				add(id[i][j],id[x][y],a[x][y]);
    			}
    	for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) f[id[i][j]][id[i][j]]=a[i][j],dji(id[i][j]);
    	for(int i=1;i<=n;i++){
    		for(int j=1;j<=m;j++){
    			for(int k=i;k<=n;k++){
    				for(int l=j;l<=m;l++){
    					if(f[id[i][j]][id[k][l]]<=T||f[id[i][l]][id[k][j]]<=T) ans=max(ans,(k-i)*(k-i)+(l-j)*(l-j));
    				}
    			}
    		}
    	}
    	double t=sqrt(ans);printf("%.6f
    ",t);
    	return 0;
    }
    
    
  • 相关阅读:
    nodejs cheerio模块提取html页面内容
    简短的perl程序
    laravel 模型操作
    Laravel 学习笔记
    记录一下应该养成的好习惯
    phpstudy设置允许远程访问mysql数据库
    删除专家账号,要注意删干净
    使用 Composer 安装Laravel扩展包的几种方法
    上传文件太大,后台无法获取到文件的问题
    在Laravel中使用mongoDB
  • 原文地址:https://www.cnblogs.com/zsq259/p/11415239.html
Copyright © 2011-2022 走看看