This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#pragma GCC optimization ("O3")
#pragma GCC optimization ("unroll-loops")
#pragma GCC optimize("Ofast")
#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
#include <string>
#include <map>
#include <unordered_map>
#include <set>
#include <unordered_set>
#include <queue>
#include <deque>
#include <list>
#include <iomanip>
#include <stdlib.h>
#include <time.h>
#include <cstring>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;
typedef long double ld;
#define REP(i,a,b) for(ll i=(ll) a; i<(ll) b; i++)
#define pb push_back
#define mp make_pair
#define pl pair<ll,ll>
#define ff first
#define ss second
#define whole(x) x.begin(),x.end()
#define DEBUG(i) cout<<"Pedro "<<i<<endl
#define INF 1000000000000000000LL
#define EPS ((ld)0.00000000001)
#define pi ((ld)3.141592653589793)
#define VV(vvvv,NNNN,xxxx); REP(iiiii,0,NNNN) {vvvv.pb(xxxx);}
ll mod=1000000007;
template<class A=ll>
void Out(vector<A> a) {REP(i,0,a.size()) {cout<<a[i]<<" ";} cout<<endl;}
template<class A=ll>
void In(vector<A> &a, ll N) {A cur; REP(i,0,N) {cin>>cur; a.pb(cur);}}
class ST
{
public:
ll N;
class SV //seg value
{
public:
ll a;
SV() {a=0LL;}
SV(ll x) {a=x;}
SV operator & (SV X) {SV ANS(a+X.a); return ANS;}
};
class LV //lazy value
{
public:
ll a;
LV() {a=0LL;}
LV(ll x) {a=x;}
LV operator & (LV X) {LV ANS(a+X.a); return ANS;}
};
SV upval(ll c) //how lazy values modify a seg value inside a node, c=current node
{
SV X(p[c].a+(range[c].ss-range[c].ff+1)*lazy[c].a);
return X;
}
SV neuts; LV neutl;
vector<SV> p;
vector<LV> lazy;
vector<pl> range;
ST() {N=0LL;}
ST(vector<ll> arr)
{
N = (ll) 1<<(ll) ceil(log2(arr.size()));
REP(i,0,2*N) {range.pb(mp(0LL,0LL));}
REP(i,0,N) {p.pb(neuts);}
REP(i,0,arr.size()) {SV X(arr[i]); p.pb(X); range[i+N]=mp(i,i);}
REP(i,arr.size(),N) {p.pb(neuts); range[i+N]=mp(i,i);}
ll cur = N-1;
while(cur>0)
{
p[cur]=p[2*cur]&p[2*cur+1];
range[cur]=mp(range[2*cur].ff,range[2*cur+1].ss);
cur--;
}
REP(i,0,2*N) {lazy.pb(neutl);}
}
void prop(ll c) //how lazy values propagate
{
p[c] = upval(c);
lazy[2*c]=lazy[c]&lazy[2*c]; lazy[2*c+1]=lazy[c]&lazy[2*c+1];
lazy[c]=neutl;
}
SV query(ll a,ll b, ll c=1LL) //range [a,b], current node. initially: query(a,b)
{
if(a>b) {return neuts;}
ll x=range[c].ff; ll y=range[c].ss;
if(y<a || x>b) {return neuts;}
if(x>=a && y<=b) {return upval(c);}
prop(c);
SV ans = query(a,b,2*c)&query(a,b,2*c+1);
return ans;
}
void update(LV s, ll a, ll b, ll c=1LL) //update LV, range [a,b], current node, current range. initially: update(s,a,b)
{
if(a>b) {return;}
ll x=range[c].ff; ll y=range[c].ss;
if(y<a || x>b) {return ;}
if(x>=a && y<=b)
{
lazy[c]=s&lazy[c];
return;
}
prop(c);
update(s,a,b,2*c); update(s,a,b,2*c+1);
p[c]=upval(2*c)&upval(2*c+1);
}
};
template<class T=ll>
class SparseTable //Range Minimum Queries
{
public:
ll N;
vector<T> a;
vector<vector<T> > v;
SparseTable() {N=0LL;}
SparseTable(vector<T> b)
{
a=b; N=a.size();
ll lo=(ll) floor((ld) log2(N)) +1LL;
vector<T> xx;
REP(i,0,lo) {xx.pb(mp(INF,INF));} REP(i,0,N) {v.pb(xx);}
REP(step,0LL,lo)
{
REP(i,0,N-(1LL<<step)+1LL)
{
if(step==0) {v[i][0]=a[i];}
else {v[i][step]=min(v[i][step-1],v[i+(1LL<<(step-1))][step-1]);}
}
}
}
T query(ll l, ll r)
{
ll step=(ll) floor((ld) log2(r-l+1LL));
return min(v[l][step],v[r-(1LL<<step)+1LL][step]);
}
};
class Tree
{
public:
ll N;
vector<ll> p;
vector<vector<ll> > sons;
vector<vector<ll> > adj;
ll root;
vector<ll> level; //starting in 0
vector<ll> val; //node values
vector<ll> DFSarr1; //DFS Array
vector<ll> DFSarr2; //DFS Array for LCA with whole path
vector<ll> pos; //inverted DFSArr, only for LCA
vector<pl> levDFSarr; //array of levels on DFSarr, only needed for LCA
vector<pl> range; vector<ll> pos1;
SparseTable<pl> S; //for LCA
vector<ll> dp0, dp1;
ST F;
vector<vector<pair<pl,ll> > > paths;
Tree(vector<vector<ll> > ad, ll r=0LL)
{
N=ad.size(); root=r; adj=ad;
vector<ll> xx; REP(i,0,N) {sons.pb(xx); p.pb(-1); level.pb(0); pos.pb(0LL); val.pb(0); dp0.pb(0); dp1.pb(0); range.pb({-1,-1}); pos1.pb(-1);}
DFS_Build(r,r);
REP(i,0,DFSarr2.size()) {pos[DFSarr2[i]]=i;}
REP(i,0,DFSarr2.size()) {levDFSarr.pb(mp(level[DFSarr2[i]],DFSarr2[i]));}
SparseTable<pl> X(levDFSarr); S=X;
F = ST(val);
paths = vector<vector<pair<pl,ll> > >(N,vector<pair<pl,ll> >());
}
void DFS_Build(ll s, ll par)
{
DFSarr1.pb(s); pos1[s]=DFSarr1.size()-1; range[s].ff=pos1[s];
DFSarr2.pb(s);
if(s!=root) {level[s]=level[par]+1LL;}
p[s]=par;
REP(i,0,adj[s].size())
{
if(adj[s][i]==par) {continue;}
sons[s].pb(adj[s][i]);
DFS_Build(adj[s][i],s);
DFSarr2.pb(s);
}
range[s].ss = DFSarr1.size()-1;
return;
}
ll LCA(ll a, ll b)
{
a=pos[a]; b=pos[b];
ll l=min(a,b); ll r=max(a,b);
pl ans=S.query(l,r);
return ans.ss;
}
ll query(ll a, ll b)
{
ll lca = LCA(a,b);
a=pos1[a]; b=pos1[b]; lca=pos1[lca];
return (F.query(a,a).a+F.query(b,b).a-F.query(lca,lca).a);
}
void update(ll s, ll x)
{
F.update(x,range[s].ff,range[s].ss);
}
void Init_paths(vector<pair<pl,ll> > p)
{
REP(i,0,p.size())
{
paths[LCA(p[i].ff.ff,p[i].ff.ss)].pb(p[i]);
}
}
void DP(ll s)
{
REP(i,0,sons[s].size()) {DP(sons[s][i]);}
ll x = 0LL; REP(i,0,sons[s].size()) {x+=dp1[sons[s][i]];}
dp0[s]=x; update(s,x);
dp1[s]=dp0[s];
ll A, B, C;
REP(i,0,paths[s].size())
{
A = paths[s][i].ff.ff; B = paths[s][i].ff.ss; C = paths[s][i].ss;
dp1[s]=max(dp1[s],C+query(A,B));
}
update(s,-dp1[s]);
}
};
int main()
{
ios_base::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
cout.precision(20);
ll N,M; cin>>N>>M;
vector<pair<pl,ll> > old_paths, paths; vector<vector<ll> > adj(N,vector<ll>());
ll A,B,C; ll ans = 0LL;
REP(i,0,M)
{
cin>>A>>B>>C; A--; B--; ans+=C;
if(C==0) {adj[A].pb(B); adj[B].pb(A);}
else {old_paths.pb({{A,B},C});}
}
Tree T(adj);
REP(i,0,old_paths.size())
{
A=old_paths[i].ff.ff; B=old_paths[i].ff.ss; C=old_paths[i].ss;
if((T.level[A]+T.level[B]+1LL)%2LL == 0) {continue;}
paths.pb(old_paths[i]);
}
T.Init_paths(paths);
T.DP(0);
cout<<ans-T.dp1[0]<<endl;
//Out(T.dp0); Out(T.dp1);
return 0;
}
Compilation message (stderr)
training.cpp:1: warning: ignoring '#pragma GCC optimization' [-Wunknown-pragmas]
1 | #pragma GCC optimization ("O3")
|
training.cpp:2: warning: ignoring '#pragma GCC optimization' [-Wunknown-pragmas]
2 | #pragma GCC optimization ("unroll-loops")
|
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |