UVAlive 5869 Airport 解题报告
来源:互联网 发布:淘宝网中华活胰宝 编辑:程序博客网 时间:2024/05/16 08:18
题目
Tri_integral Trainning 4
题意:
一个图,有两种点:旅店和旅客中心。要建一个机场p,对于每个旅店i,用 s(p,i)表示从机场到某个旅客中心再到这个旅店的最短距离。每个旅店有一个旅客人数t(i),要使 s(p, i)×t(i)的最大值最小。机场可以建在任意点上或边的某个位置上。
题解:
首先用floyd处理任意一个点作为机场的各 s(p, i)。然后枚举每条边二分答案:
对于二分的答案mid,任意 s(p, i)×t(i)都不能这个值,但是机场可能先经过枚举的边的u或者先经过v,所以对先经过u,可以计算出一个区间[l,r],机场建在这个范围内对旅店i都可以接受,对v同理。所以对所有的旅店,每个旅店选一个区间,只要公共部分存在,就说明存在一段区间使机场建在这个位置对所有旅店都不超过mid。
但是直接这样写会T,因为最坏情况有2^n个区间,要剪枝:如果这两个区间有交集,说明机场对这个旅店不管建在该边上哪里都可以(两个区间一个左端点一定为0,一个右端点一定为w),所以可以不更新区间。
这样虽然能过但还是很慢,再加几个:
1、如果u和v都是旅店那找不出更优解(因为一定要先经过一个旅客中心,注意是更优不是最优),所以省掉没关系。
2、先算一下建在点上最小的答案,二分的时候以这个为上限,并且二分前先算下以上限为mid是否能接受。
//Time:86ms//Memory:0KB//Length:3401B#include <iostream>#include <cstdio>#include <cstdlib>#include <string>#include <cstring>#include <algorithm>#include <vector>#include <cmath>#include <map>#include <queue>#define MAXN 301#define MAXM 10000#define MP(x,y) make_pair(x,y)#define FI first#define SE second#define EPS 1e-6#define PDD pair<double,double>using namespace std;int dist[MAXN][MAXN];int ma[MAXN][MAXN];int uu[MAXM],vv[MAXM],ww[MAXM],th[MAXM];double ans;inline PDD npair(PDD a,PDD b){ return MP(max(a.FI,b.FI),min(a.SE,b.SE));}vector<PDD > check(int u,int v,int w,int h,double tans,vector<PDD >&ori,vector<PDD > &vec){ PDD inte1,inte2; if(1.0*ma[u][h]*th[h]>tans-EPS) inte1=MP(1e10,-1e10); else if(1.0*(ma[u][h]+w)*th[h]>tans-EPS) inte1=MP(0,tans/th[h]-ma[u][h]); else inte1=MP(0,w); if(1.0*ma[v][h]*th[h]>tans-EPS) inte2=MP(1e10,-1e10); else if(1.0*(ma[v][h]+w)*th[h]>tans-EPS) inte2=MP(0,tans/th[h]-ma[v][h]); else inte2=MP(0,w); inte2.FI=w-inte2.FI,inte2.SE=w-inte2.SE; swap(inte2.FI,inte2.SE); if(inte1.SE>inte2.FI-EPS) inte1=MP(0,w), inte2=MP(1e10,-1e10); for(int i=0;i<ori.size();++i) { PDD tmp; if(inte1.FI<inte1.SE+EPS) { tmp=npair(inte1,ori[i]); if(tmp.FI<tmp.SE) vec.push_back(tmp); } if(inte2.FI<inte2.SE+EPS) { tmp=npair(inte2,ori[i]); if(tmp.FI<tmp.SE) vec.push_back(tmp); } } return vec;}bool cal(double mid,int n,int u,int v,int w){ int s=0; vector<PDD > interval[2]; interval[s].push_back(MP(0,w)); for(int i=1;i<=n;++i) { interval[!s].clear(); check(u,v,w,i,mid,interval[s],interval[!s]); s=!s; if(interval[s].size()==0) return false; } return true;}double mfind(int u,int v,int w,int n){ double l=0,mid,ret=1e100,r=ans; mid=ans; if(!cal(mid,n,u,v,w)) return ret; while(l<r-EPS) { mid=(l+r)/2; if(cal(mid,n,u,v,w)) r=ret=mid; else l=mid; } return ret;}int main(){ //freopen("H:\\MyDocument\\Code\\input.txt","r",stdin); int n,k,m; while(scanf("%d%d%d",&n,&k,&m)==3) { if(!n&&!k&&!m) break; memset(dist,0x3f,sizeof(dist)); memset(ma,0x3f,sizeof(ma)); for(int i=1;i<=n+k;++i) dist[i][i]=0; for(int i=0;i<m;++i) scanf("%d%d%d",&uu[i],&vv[i],&ww[i]), dist[uu[i]][vv[i]]=dist[vv[i]][uu[i]]=ww[i]; for(int l=1;l<=n+k;++l) for(int i=1;i<=n+k;++i) for(int j=1;j<=n+k;++j) dist[i][j]=min(dist[i][l]+dist[l][j],dist[i][j]); for(int l=n+1;l<=n+k;++l) for(int i=1;i<=n+k;++i) for(int j=1;j<=n;++j) ma[i][j]=min(ma[i][j],dist[i][l]+dist[l][j]); for(int i=1;i<=n;++i) scanf("%d",&th[i]); ans=1e100; for(int i=1;i<=n+k;++i) { double tmp=0; for(int j=1;j<=n;++j) tmp=max(tmp,1.0*th[j]*ma[i][j]); ans=min(ans,tmp); } for(int i=0;i<m;++i) if(uu[i]>n||vv[i]>n) ans=min(ans,mfind(uu[i],vv[i],ww[i],n)); printf("%.3f\n",ans); } return 0;}
- UVAlive 5869 Airport 解题报告
- UVALive 5797解题报告
- UVALive 5986解题报告
- UVAlive 6151 Beehives 解题报告
- UVAlive 6160 Countdown 解题报告
- UVa 1450 Airport 解题报告(二分+策略)
- UVALive 4725 Airport 【DP】
- UVALive - 4725 Airport
- UVaLive 6038 - Grandpa's Walk 解题报告
- UVAlive 6040 Stop Growing! 解题报告
- UVALive 6044 Unique Path 解题报告
- UVALive 6047 Perfect Matching 解题报告
- UVALive 6179 Windmill Animation 解题报告
- UVALive 5861 Hidden Terminal Problem 解题报告
- UVALive 5862 City Travel 解题报告
- UVALive 5864 Register Allocation 解题报告
- UVAlive 6152 Bits Equalizer 解题报告
- UVAlive 6153 LCM Pair Sum 解题报告
- hdu1402 傅里叶变换
- 关于赛车游戏制作的一点体会
- [poj 1182]食物链[并查集][图解+注释]
- Java学习之道:hibernate二级缓存的实现
- 淘宝天猫店铺微信公众平台建设指南
- UVAlive 5869 Airport 解题报告
- QT 实现QLabel上的超链接
- POJ 2411 Mondriaan's Dream
- OC多线程
- Matlab学习笔记五:字符串操作
- 个人博客开发总结
- activity跳转
- 运动检测(前景检测)之(一)ViBe
- c++初步小程序