考试多思考,认真对待每场考试。
仍旧一个问题,考到一半就放弃了。主要是怕打不完,T2只码了个暴力,T1没有深度思考,只是在皮上画画写写,也许这种情况下已经没法思考了。下次考试看看能不能静下心来思考,不要慌。
T1:很好的一道题,想到了要判是不是一些块把某一条路封死了,但是我一想它可能不是一条竖线上就觉得比较麻烦,横着错开比较难判,但是图论就是干这个的,你把所有点向上下边界建边,上边界到下边界的最大值最小的一条路径就是瓶颈,走的时候总会穿过一条最长的路径。这就不用看点与点是不是在一条竖线上,其实是我们不关心它的位置,我只关心点与点的距离,然后这样不关心在坐标轴位置的东西,图论建成边,就能只考虑相对位置了。
#include<iostream> #include<cstdio> #include<cmath> #include<queue> #include<cstring> using namespace std; const int N=6020; double d[N]; bool v[N]; int pr[N],n,m,k; struct point{double x,y;}p[N]; inline int rd() { int s=0,w=1; char cc=getchar(); for(;cc<'0'||cc>'9';cc=getchar())if(cc=='-') w=-1; for(;cc>='0'&&cc<='9';cc=getchar()) s=(s<<3)+(s<<1)+cc-'0'; return s*w; } inline double cal(int i,int j) { if(i==k&&j==k-1) return 0x7fffffff; if(j==k&&i==k-1) return 0x7fffffff; if(i==k) return m-p[j].y; if(j==k) return m-p[i].y; if(i==k-1) return p[j].y; if(j==k-1) return p[j].y; point a=p[i],b=p[j]; return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); } inline void prim() { for(int i=1;i<=k;i++) d[i]=0x7fffffff; memset(v,0,sizeof(v)); d[k-1]=0; for(int i=1;i<=k;i++) { int x=0; for(int j=1;j<=k;j++) if(!v[j]&&(x==0||d[j]<d[x])) x=j; v[x]=1; for(int j=1;j<=k;j++) if(!v[j]) { if(cal(x,j)<d[j]) { d[j]=cal(x,j); pr[j]=x; } } } } int main() { n=rd();m=rd();k=rd(); for(int i=1;i<=k;i++) { double x=rd(),y=rd(); p[i]=(point){x,y}; } k+=2; prim(); int tmp=k; double ans=-0x7fffffff; while(tmp!=k-1) { ans=max(ans,d[tmp]); tmp=pr[tmp]; } printf("%.10lf\n",ans/2); } /* g++ -std=c++11 1.cpp -o 1 ./1 10 5 2 1 1 2 3 */