2011亚洲区预选赛北京赛区 第一题 dfs||bfs预处理一个dp
表示原来用RMQ和LCA做的方法烦了,现在直接在建最小生成树的过程中建双向边就好了, cost[i][j]表示i到j的最长树边
View Code
1 #include<string.h>
2 #include<stdio.h>
3 #include<vector>
4 #include<math.h>
5 #include<queue>
6 using namespace std;
7 const int M =1010;
8 const double inf = 1e20;
9 double max(double a,double b){return a>b?a:b;}
10 int n,k;
11 int used[M];
12 double di[M][M],cost[M][M];
13 vector<int> edge[M];
14 struct point {
15 double x,y,p;
16 }p[1010];
17 bool flag[M];
18 double D[M];
19 int pre[M];
20 double prime(int s,int n)
21 {
22 int i,v,k;
23 double mi;
24 double ret=0;
25 for(i=1;i<=n;i++)
26 {
27 flag[i]=0;
28 D[i]=inf;
29 pre[i]=-1;
30 }
31 D[s]=0;
32 for(k=0;k<n;k++)
33 {
34 mi=inf;
35 for(i=1;i<=n;i++)if(!flag[i])
36 {
37 if(D[i]<mi)
38 {
39 mi=D[i];
40 v=i;
41 }
42 }
43 ret+=mi;
44 flag[v]=1;
45 if(pre[v]!=-1)
46 {
47 edge[pre[v]].push_back(v);
48 edge[v].push_back(pre[v]);//Ò»¶¨ÒªË«Ïò½¨±í£¬ÒòΪҪÇó³öÈÎÒâÁ½µã¼äµÄ×Ê÷±ß
49 }
50 for(i=1;i<=n;i++)if(!flag[i])
51 {
52 if(di[v][i]<D[i])
53 {
54 D[i]=di[v][i];
55 pre[i]=v;
56 }
57 }
58 }
59 return ret;
60 }
61 double dis(point a,point b)
62 {
63 return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
64 }
65 void cal(int S,int s)
66 {
67 int i,t;used[s]=1;
68 for(i=0;i<edge[s].size();i++)
69 {
70 t=edge[s][i];if(used[t]) continue;
71 cost[S][t]=max(di[s][t],cost[S][s]);
72 cal(S,t);
73 }
74 }
75 void bfs(int S)
76 {
77 int i,t;
78 queue<int> Q;
79 Q.push(S);
80 while(!Q.empty())
81 {
82 int s=Q.front();Q.pop();
83 used[s]=1;
84 for(i=0;i<edge[s].size();i++)
85 {
86 t=edge[s][i];if(used[t]) continue;
87 cost[S][t]=max(di[s][t],cost[S][s]);
88 Q.push(t);
89 }
90 }
91 }
92 int main()
93 {
94 int t,i,j;
95 scanf("%d",&t);
96 while(t--)
97 {
98 scanf("%d",&n);
99 for(i=1;i<=n;i++)
100 scanf("%lf%lf%lf",&p[i].x,&p[i].y,&p[i].p);
101 for(i=1;i<=n;i++)
102 {
103 edge[i].clear();
104 cost[i][i]=0;
105 di[i][i]=0;
106 for(j=i+1;j<=n;j++)
107 {
108 cost[j][i]=cost[i][j]=-1;
109 di[j][i]=di[i][j]=dis(p[i],p[j]);
110 }
111 }
112 double mm=prime(1,n);
113 memset(used,0,sizeof(used));
114 double ans=0,tmp;
115 for(i=1;i<=n;i++)
116 {
117 memset(used,0,sizeof(used));
118 bfs(i);
119 //cal(i,i);
120 }
121 for(i=1;i<=n;i++)
122 {
123 for(j=i+1;j<=n;j++)
124 {
125 double temp;
126 temp=cost[i][j];
127 tmp=mm-temp;
128 tmp=(p[i].p+p[j].p)/tmp;
129 if(tmp>ans) ans=tmp;
130 }
131 }
132 printf("%.2lf\n",ans);
133 }
134 return 0;
135 }
136 /*
137 2
138 4
139 1 1 20
140 1 2 30
141 200 2 80
142 200 1 100
143 3
144 1 1 20
145 1 2 30
146 2 2 40
147 */