jzoj100042-保留道路【最小生成树,图论】
生活随笔
收集整理的這篇文章主要介紹了
jzoj100042-保留道路【最小生成树,图论】
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
正題
題目大意
一張無向圖,求剩下一些邊使圖聯通且wG?max{gVi}+wS?max{sVi}wG*max\{g_{V_i}\}+wS*max\{s_{V_i}\}wG?max{gVi??}+wS?max{sVi??}最小
VVV表示選的邊集
解題思路
我們可以枚舉max{si}max\{s_i\}max{si?}的值,然后用ggg跑最小生成樹。時間復雜度O(m2)O(m^2)O(m2),就可以成功TLETLETLE
這時,就需要用到最小生成樹的性質。對于新的一個max{si}max\{s_i\}max{si?},你只能加入一條新的邊,直接用這個加進去跑一邊最小生成樹就好了。
codecodecode
#include<cstdio> #include<algorithm> #define Inf 1e18 #define N 500 #define M 50010 #define ll long long using namespace std; struct node{ll x,y,g,s; }a[M]; ll n,m,wS,wG,ans,tot; ll fa[N],s[M],p[N]; bool cmp(node x,node y) {return x.g<y.g;} ll find(ll x) {return fa[x]==x?x:fa[x]=find(fa[x]);} void unionn(ll x,ll y) {ll Fa=find(x),Fb=find(y);if(Fa<Fb) fa[Fb]=Fa;else fa[Fa]=Fb; } int main() {scanf("%lld%lld%lld%lld",&n,&m,&wG,&wS);for(ll i=1;i<=m;i++){scanf("%lld%lld%lld%lld",&a[i].x,&a[i].y,&a[i].g,&a[i].s);}ans=Inf;sort(a+1,a+1+m,cmp);for(ll i=1;i<=m;i++){if(a[i].x==a[i].y)continue;ll j,k=0,cnt=0;for(j=1;j<=n;j++)fa[j]=j;for(j=tot;j>=1;j--)if(a[p[j]].s>a[i].s) p[j+1]=p[j];else break;p[j+1]=i;tot++;for(j=1;j<=tot;j++){if(find(a[p[j]].x)!=find(a[p[j]].y)){unionn(a[p[j]].x,a[p[j]].y);k=max(k,a[p[j]].s);p[++cnt]=p[j];}if(cnt==n-1) break;}if(cnt==n-1) ans=min(ans,k*wS+a[i].g*wG);tot=cnt;}if(ans==Inf) printf("-1");else printf("%lld",ans); }總結
以上是生活随笔為你收集整理的jzoj100042-保留道路【最小生成树,图论】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 小蟑螂怎么消灭最彻底 消灭小蟑螂的六个小
- 下一篇: jzoj5123-diyiti【统计,容