jzoj3410-[GDOI2014模拟]Tree【最小生成树,贪心】
生活随笔
收集整理的這篇文章主要介紹了
jzoj3410-[GDOI2014模拟]Tree【最小生成树,贪心】
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
正題
題目大意
在一張圖中選擇一顆生成樹使得邊權的方差最小。
解題思路
我們很容易想到一種貪心,那就是在按照邊權排好序后選擇一段連續的區間然后使用這段區間構成最小生成樹,這樣時間復雜度是O(m3log?m)O(m^3\log m)O(m3logm),時間復雜度難以接受。
那我們可以考慮枚舉一個數xxx(精度在0.10.10.1內即可),然后將邊權按照∣w?x∣|w-x|∣w?x∣排序,然后優先選取。每次枚舉取最小值。
時間復雜度O(1000?mlog?m)O(1000*m\log m)O(1000?mlogm),可以通過本題。
codecodecode
#include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; const int N=2110; struct node{int x,y;double w,c;bool ok; }a[N]; int n,m,fa[N]; double ans; bool cMp(node x,node y) {return x.w<y.w;} int find(int x) {return fa[x]==x?x:fa[x]=find(fa[x]);} double check(double k) {for(int i=1;i<=n;i++)fa[i]=i;for(int i=1;i<=m;i++)a[i].w=fabs(a[i].c-k),a[i].ok=0;sort(a+1,a+1+m,cMp);double ave=0,ans=0;for(int i=1;i<=m;i++)if(find(a[i].x)!=find(a[i].y))fa[fa[a[i].x]]=fa[a[i].y],ave+=a[i].c,a[i].ok=1;ave/=1.0*(n-1);for(int i=1;i<=m;i++)if(a[i].ok) ans+=(a[i].c-ave)*(a[i].c-ave);return sqrt(ans/(1.0*(n-1))); } int main() {scanf("%d%d",&n,&m);for(int i=1;i<=m;i++)scanf("%d%d%lf",&a[i].x,&a[i].y,&a[i].c);ans=2147483647;for(double i=0;i<=100;i+=0.1)ans=min(ans,check(i));printf("%.4lf",ans); } 創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的jzoj3410-[GDOI2014模拟]Tree【最小生成树,贪心】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: jzoj2908,P1527-[集训队互
- 下一篇: jzoj3682-Points and