• 题解 [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;
    }
    
    
  • 相关阅读:
    [linux] ubuntu gnome 控制面板恢复
    [linux] grub修改
    [erlang] 合并list
    hdu4169 Wealthy Family (树形背包)
    hdu 3899 JLUCPC
    最大流模板
    hdu 4167 User Names
    hdu 2196 Computer (树形DP)
    hdu 1011 Starship Troopers(树形DP)
    hdu 2874 Connections between cities (LCA转RMQ)
  • 原文地址:https://www.cnblogs.com/zsq259/p/11415239.html
Copyright © 2020-2023  润新知