题意:给出一张图,图中的每个节点,每条边都有一个权值,现在有从中挑出一张子图,要求子图联通,并且被选中的任意两点,如果存在边,则一定要被选中。问说点的权值和/边的权值和最大是多少。
分析:
必然存在一条边数≤1的最优解
假设存在最优解(G)ans最小边数>1,则点数>2
ans=∑vi/∑c
由假设知对G的子图,(u+v)/c<ans ,(u+v)<ans*c
∴∑u+∑v<ans*∑c ,(∑u+∑v)/∑c<ans=∑vi/∑c
∴(∑u+∑v)<∑vi 矛盾
结论成立
所以只要判断所有的只取1条边,和不取的情况 O(m)
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
double v[555];
int main()
{
int n,m;
scanf("%d%d",&n,&m);
int i;
for(i=1;i<=n;i++) scanf("%lf",&v[i]);
double ans=0;
while(m--)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
double t=(v[a]+v[b])/c;
ans=max(t,ans);
}
printf("%.15lf",ans);
return 0;
}