Topic index: https://www.lydsy.com/JudgeOnline/problem.php?id=2654
2654: tree
Time Limit: 30 Sec Memory Limit: 512 MBSubmit: 2768 Solved: 1136
[ Submit ][ Status ][ Discuss ]
Description
Input
Output
Sample Input
0 1 1 1
0 1 2 0
Sample Output
HINT
The original data is wrong, it has been updated by liutian , but not retested---2016.6.24
Source
Topic Analysis:
Find the weight of the minimum spanning tree that satisfies the meaning of the question -> first meet the requirements -> the selected minimum spanning tree has a need white edge -> but the selected minimum spanning tree does not necessarily have a need white edge -> For each time Kruskal-> we can get the number of white edges in the current minimum spanning tree Cnt-> if Cnt>need->the number of white edges is more than needed->the weight of the white edges is too small->make each A value is added to each white edge -> it is possible to reduce the Cnt counted by Kruskal the next time -> if the number of Cnt<need -> the number of white edges is less than required -> the weight of the white edge is too large -> Subtract a value from each white edge -> Make it possible to increase the Cnt counted by Kruskal next time -> How do we modify the weight of the white edge -> How much to modify the weight of the white edge -> Get the solution -> Dichotomous answer + spanning tree.
code show as below:
#include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define DB double #define SG string #define LL long long #define Fp(A,B,C,D) for(A=B;A<=C;A+=D) #define Fm(A,B,C,D) for(A=B;A>=C;A-=D) #define Clear(A) memset(A,0,sizeof(A)) using namespace std; const LL Max=1e5+5; const LL Mod=1e9+7; const LL Inf=1e18; struct Node{ LL C,X,Y,V; void Get(LL A,LL B,LL P,LL Q){ C=A;X=B;Y=P;V=Q; } }G[Max<<1]; LL N,M,W,Ans,Cnt,Tot,Left=-105,Mid,Right=105,C[Max<<1],X[Max<<1],Y[Max<<1],V[Max<<1],F[Max<<1]; inline LL Read(){ LL X=0;char CH=getchar();bool F=0; while(CH>'9'||CH<'0'){if(CH=='-')F=1;CH=getchar();} while(CH>='0'&&CH<='9'){X=(X<<1)+(X<<3)+CH-'0';CH=getchar();} return F?-X:X; } inline void Write(LL X){ if(X<0)X=-X,putchar('-'); if(X>9)Write(X/10); putchar(X%10+48); } bool Cmp(Node A,Node B){ return A.V==B.V?A.C<B.C:A.V<B.V; } LL Find(LL X){ return F[X]==X?X:Find(F[X]); } void Kruskal(){ LL I,J,K;Ans=Cnt=0; Fp(I,1,N,1){ F[I]=I; } Fp(I,1,M,1){ G[I].Get(C[I],X[I],Y[I],V[I]); if(!G[I].C){ G[I].V-=Mid; } }sort(G+1,G+1+M,Cmp); Fp(I,1,M,1){ LL P=Find(G[I].X); LL Q=Find(G[I].Y); if(P!=Q){ F[P]=Q; Ans+=G[I].V; if(!G[I].C){ Cnt++; } } } } int main(){ LL I,J,K; N=Read(),M=Read(),W=Read(); Fp(I,1,M,1){ X[I]=Read()+1; Y[I]=Read()+1; V[I]=Read(); C[I]=Read(); } while(Left<=Right){ Mid=Left+Right>>1; Kruskal(); if(Cnt>=W){ Right=Mid-1; Tot=Ans+W*Mid; } else { Left=Mid+1; } }Write(Tot); return 0; }