hdu 4081 最小生成树+树形dp
思路:直接先求一下最小生成树,然后用树形dp来求最优值。也就是两遍dfs。
#include<iostream> #include<algorithm> #include<cstdio> #include<cstring> #include<cmath> #define Maxn 2010 using namespace std; struct Edge{ int u,v; double c; int operator <(const Edge &temp) const { return c<temp.c; } }p[1000010]; struct PP{ int u,v,next; double val; }edge[Maxn*2]; struct Point{ double x,y; }city[Maxn]; int set[Maxn],e,vi[10010],num[Maxn],head[Maxn],road[Maxn],Max[Maxn],lMax[Maxn]; double ans,S; int find(int x) { if(x!=set[x]) set[x]=find(set[x]); return set[x]; } int merg(int a,int b) { int x,y; x=find(a); y=find(b); if(x==y) return 0; set[x]=y; return 1; } void add(int u,int v,double val) { edge[e].u=u,edge[e].v=v,edge[e].val=val,edge[e].next=head[u],head[u]=e++; edge[e].u=v,edge[e].v=u,edge[e].val=val,edge[e].next=head[v],head[v]=e++; memset(Max,0,sizeof(Max)); } double DIS(Point a,Point b) { return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); } void init() { for(int i=0;i<Maxn;i++) set[i]=i,num[i]=0; memset(head,-1,sizeof(head)); memset(vi,0,sizeof(vi)); memset(road,0,sizeof(road)); e=0; } void dfs(int u) { int i,v; vi[u]=1; Max[u]=lMax[u]=num[u]; for(i=head[u];i!=-1;i=edge[i].next){ v=edge[i].v; if(vi[v]) continue; dfs(v); if(Max[v]>Max[u]){ lMax[u]=Max[u]; Max[u]=Max[v]; road[u]=v; } else if(Max[v]>lMax[u]){ lMax[u]=Max[v]; } } } void predfs(int u,int sum) { int i,v; vi[u]=1; double a,b; for(i=head[u];i!=-1;i=edge[i].next){ v=edge[i].v; if(vi[v]) continue; if(road[u]==v) a=max(lMax[u],sum); else a=max(sum,Max[u]); a+=Max[v]; b=S-edge[i].val; if(a/b>ans){ ans=a/b; } if(road[u]==v) predfs(v,max(lMax[u],sum)); else predfs(v,max(Max[u],sum)); } } int main() { int t,n,m,i,j,x,y,c; scanf("%d",&t); while(t--) { init(); scanf("%d",&n); for(i=1;i<=n;i++) scanf("%lf%lf%d",&city[i].x,&city[i].y,&num[i]); int cnt=0; for(i=1;i<=n;i++){ for(j=i+1;j<=n;j++){ p[++cnt].u=i,p[cnt].v=j,p[cnt].c=DIS(city[i],city[j]); } } sort(p+1,p+1+cnt); int cc=0; double temp=0; int lis[Maxn]; for(i=1;i<=cnt;i++){ if(merg(p[i].u,p[i].v)){ temp+=p[i].c; lis[++cc]=i; } if(cc==n-1) break; } for(i=1;i<=cc;i++){ add(p[lis[i]].u,p[lis[i]].v,p[lis[i]].c); } S=temp; ans=0; dfs(1); memset(vi,0,sizeof(vi)); predfs(1,0); printf("%.2lf\n",ans); } return 0; }