题目:https://www.luogu.org/problemnew/show/P1522
简单地求了一堆最短路而已。
1.有时候sqrt里要 * 1.0,不知何故;本题需要吗?
2.那个地方是 f [ col [ cur ] ],不是 f [ cnt ]!
*3.原来可以输入 .1%d 来限制输入一位数字,很方便!
#include<iostream> #include<cstdio> #include<cstring> #include<queue> #include<cmath> #define ll long long using namespace std; const int N=155;const double INF=1e9+5; int n,x[N],y[N],col[N],head[N],xnt,cnt; bool b[N][N],vis[N],in[N]; double dis[N][N],c[N],fx[N],f[N],ans; struct Edge{ int next,to; double w; Edge(int n=0,int t=0,double w=0):next(n),to(t),w(w) {} }edge[N*N<<1]; double calc(int i,int j) {return sqrt(1.0*(x[i]-x[j])*(x[i]-x[j])+1.0*(y[i]-y[j])*(y[i]-y[j]));} void add(int x,int y) { double tp=calc(x,y); edge[++xnt]=Edge(head[x],y,tp);head[x]=xnt; edge[++xnt]=Edge(head[y],x,tp);head[y]=xnt; } void dj(int cur,bool cs) { priority_queue<pair<double,int>,vector<pair<double,int> >,greater<pair<double,int> > > q; memset(in,0,sizeof in); for(int i=1;i<=n;i++)c[i]=INF; c[cur]=0;q.push(make_pair(0,cur)); while(q.size()) { int k=q.top().second;q.pop(); while(in[k]&&q.size())k=q.top().second,q.pop(); if(in[k])break; in[k]=1;if(cs)col[k]=cnt;fx[cur]=max(fx[cur],c[k]); for(int i=head[k],v;i;i=edge[i].next) if(c[k]+edge[i].w<c[v=edge[i].to]) { c[v]=c[k]+edge[i].w;q.push(make_pair(c[v],v)); } } f[col[cur]]=max(f[col[cur]],fx[cur]);//不是f[cnt] } int main() { scanf("%d",&n); for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)dis[i][j]=INF; for(int i=1;i<=n;i++)scanf("%d%d",&x[i],&y[i]);bool tp=0; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { scanf("%1d",&tp);if(tp)add(i,j);// } for(int i=1;i<=n;i++) if(!vis[i]) { int cs=0; vis[i]=1;if(!col[i])cnt++,cs=1; dj(i,cs); } ans=INF; for(int i=1;i<n;i++) for(int j=i+1;j<=n;j++) if(col[i]!=col[j]) ans=min(ans,max(fx[i]+fx[j]+calc(i,j),max(f[col[i]],f[col[j]]))); printf("%.6lf",ans); return 0; }