BZOJ1295 [SCOI2009]最长距离 智商

大体就是给一个01矩阵,1不可通行,可以破坏k[0,30]个1方格,问最长欧式距离

脑洞1小时没啥想法。。给正解跪。。居然是跑破坏方块的最短路,然后枚举点对更新答案,只要点对的最短路距离<=k就合法

naive!

#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<queue>
#include<string.h>
#include<math.h>
#include<set>
#include<map>
#include<vector>
#include<iomanip>
#include<stack>
using namespace std;
#define ll long long
#define ull unsigned long long
#define pb push_back
#define mem(a) memset(a,0,sizeof a)
#define FOR(a) for(int i=1;i<=a;i++)
#define sqr(a) (a)*(a)

const int maxn=35*35;
const ll mod=1e9+7;

int n,m,t;

char buf[maxn];
int mp[maxn][maxn]; 

struct EDGE{int v,w;};
vector<EDGE>G[maxn];
void addedge(int u,int v,int w){
	G[u].pb((EDGE){v,w});
}
struct NODE{
	int v,d;
	friend bool operator<(NODE a,NODE b){return a.d>b.d;}
};
int d[maxn][maxn],vis[maxn];
void dij(int from){
	memset(vis,0,sizeof vis);
	for(int i=0;i<maxn;i++)d[from][i]=mod;
	if(!mp[(from+m-1)/m][from%m!=0?from%m:m])d[from][from]=0;
	else d[from][from]=1;
	priority_queue<NODE>Q;
	NODE now=(NODE){from,0};
	Q.push(now);
	while(!Q.empty()){
		NODE now=Q.top();Q.pop();
		int u=now.v;
		if(vis[u])continue;
		vis[u]=1;
		for(int i=0;i<G[u].size();i++){
			if(d[from][G[u][i].v]>d[from][u]+G[u][i].w){
				d[from][G[u][i].v]=d[from][u]+G[u][i].w;
				NODE nxt=(NODE){G[u][i].v,d[from][G[u][i].v]};
				Q.push(nxt);
			}
		}
	}
}

int main(){
	scanf("%d%d%d",&n,&m,&t);
	for(int i=1;i<=n;i++){
		scanf("%s",buf+1);
		for(int j=1;j<=m;j++)mp[i][j]=buf[j]=='1'?1:0;
	}

	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			int x=i,y=j;
			for(int dx=-1;dx<=1;dx++){
				for(int dy=-1;dy<=1;dy++){
					if(dx==dy || dx+dy==0)continue;
					if(x+dx>n||x+dx<1||y+dy>m||y+dy<1)continue;
					if(mp[x+dx][y+dy]){
						addedge((x-1)*m+y,(x+dx-1)*m+y+dy,1);					
					}else{
						addedge((x-1)*m+y,(x+dx-1)*m+y+dy,0);
					}
				}
			}	
		}
	}
	for(int i=1;i<=n*m;i++){
		dij(i);
	}
	double ans=0;
	for(int i=1;i<=n*m;i++){
		for(int j=1+i;j<=n*m;j++){
			if(d[i][j]<=t){

				int yy1=i%m==0?m:i%m;
				int yy2=j%m==0?m:j%m;
				//if(mp[(i+m-1)/m][yy1])if(d[i][j]==t-1)continue;
				ans=max(ans,sqrt(sqr((i+m-1)/m-(j+m-1)/m) + sqr(yy1-yy2)));
			}
		}
	}
	printf("%.6lf\n",ans);
}



posted @ 2017-11-11 21:59  Drenight  阅读(139)  评论(0编辑  收藏  举报