http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1640
At first, when you see that you want to minimize the maximum, it's definitely a two-point maximum, and then run every time Kruskal
The complexity is O (E * 64), and then the card is tle.
Then when observing the Kruskal, if the largest side is Val, then the larger than Val is not, then the entire array is also ordered.
such as 7, 6, 5, 4, 3, 2, 1, and so on, this can also be lower_bound, and then Lower_bound can be, 600ms
After changing the lower_bound, I forgot to delete the IF, actually still timed out. TAT, this data is a bit strong.
#include <cstdio>#include<cstdlib>#include<cstring>#include<cmath>#include<algorithm>#include<assert.h>#defineIOS Ios::sync_with_stdio (False)using namespacestd;#defineINF (0X3F3F3F3F)typedefLong Long intLL; #include<iostream>#include<sstream>#include<vector>#include<Set>#include<map>#include<queue>#include<string>#include<bitset>intN, M;Const intMAXN = 2e5 + -;structEdge {intu, V, W; BOOL operator< (Const structEdge & RHS)Const { returnW >RHS.W; }}E[MAXN];intFA[MAXN];voidinit () { for(inti =1; I <= N; ++i) Fa[i] =i;}intTofind (intu) {if(Fa[u] = = u)returnu; Else returnFa[u] =Tofind (Fa[u]);}voidTomerge (intXinty) {x=tofind (x); Y=tofind (y); Fa[y]=x;} LL Nowans;BOOLCheck (LL val) {init (); intSEL =0; Nowans=0; structEdge t; T.W=Val; intpos = Lower_bound (e +1, E +1+ M, t)-e; for(inti = pos; I <= m; ++i) {//if (E[i].w > Val) continue; Card Tle if(Tofind (e[i].u) = = Tofind (E[I].V))Continue; Tomerge (e[i].u, E[I].V); Nowans+=E[I].W; Sel++; if(sel = = N-1) { return true; } } return false;}voidWork () {scanf ("%d%d", &n, &m); LL Lo= 1e18l, hi =-1e18l; for(inti =1; I <= m; ++i) {scanf ("%d%d%d", &e[i].u, &E[I].V, &E[I].W); Lo=min (lo, (LL) E[I].W); Hi=Max (Hi, (LL) E[I].W); } sort (E+1, E +1+m); while(Lo <=hi) {LL Mid= (lo + hi) >>1; if(check (mid)) {Hi= Mid-1; } ElseLo = mid +1; } check (lo);//printf ("%lld\n", Nowans);cout << Nowans <<Endl;//struct Edge t;//T.W = 3;//int pos = lower_bound (e + 1, E + 1 + M, t)-E;//cout << pos << Endl;}intMain () {#ifdef local freopen ("Data.txt","R", stdin);//freopen ("Data.txt", "w", stdout);#endifWork (); return 0;}
View Code
Then I went online to see the solution, and then found that their approach is very complex.
The feeling is that test instructions makes us want to complicate, and the magic value, and the sum,
The positive solution is Kruskal two times, the first time can find the maximum value of the smallest, and then from the big Kruskal again.
But why still 700ms, a bit of a pit.
#include <cstdio>#include<cstdlib>#include<cstring>#include<cmath>#include<algorithm>#include<assert.h>#defineIOS Ios::sync_with_stdio (False)using namespacestd;#defineINF (0X3F3F3F3F)typedefLong Long intLL; #include<iostream>#include<sstream>#include<vector>#include<Set>#include<map>#include<queue>#include<string>#include<bitset>intN, M;Const intMAXN = 2e5 + -;structNode {intu, V, W; BOOL operator< (Const structNode & RHS)Const { returnW <RHS.W; }}E[MAXN];BOOLcmpstructNode A,structNode B) { returnA.W >B.W;}intFA[MAXN];intTofind (intu) {if(Fa[u] = = u)returnu; Else returnFa[u] =Tofind (Fa[u]);}voidTomerge (intXinty) {x=tofind (x); Y=tofind (y); Fa[y]=x;}voidinit () { for(inti =1; I <= N; ++i) Fa[i] =i;}intresult () {init (); intSEL =0; for(inti =1; I <= m; ++i) {if(Tofind (e[i].u) = = Tofind (E[I].V))Continue; Tomerge (e[i].u, E[I].V); Sel++; if(sel = = N-1)returnE[I].W; }}voidWork () {scanf ("%d%d", &n, &m); for(inti =1; I <= m; ++i) {scanf ("%d%d%d", &e[i].u, &E[I].V, &E[I].W); } sort (E+1, E +1+m); intMX =result (); Sort (e+1, E +1+m, CMP); Init (); LL ans=0; intSEL =0; for(inti =1; I <= m; ++i) {if(E[I].W > MX)Continue; if(Tofind (e[i].u) = = Tofind (E[I].V))Continue; Tomerge (e[i].u, E[I].V); Sel++; Ans+=E[I].W; if(sel = = N-1) Break; } printf ("%lld\n", ans);//cout << ans << endl;}intMain () {#ifdef local freopen ("Data.txt","R", stdin);//freopen ("Data.txt", "w", stdout);#endifWork (); return 0;}
View Code
51nod 1640 Magic two points + Kruska algorithm (Kruskal algorithm) it's complicated.