# | 제출 시각 | 아이디 | 문제 | 언어 | 결과 | 실행 시간 | 메모리 |
---|---|---|---|---|---|---|---|
1121346 | tfgs | Training (IOI07_training) | C++17 | 0 ms | 0 KiB |
이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include <bits/stdc++.h>
using namespace std;
#define int int64_t
const int inf=1e18;
#ifdef LOCAL
#include "algo/debug.h"
#else
template <typename... Args>
void dummy(Args&&... args){}
#define ps dummy
#endif
#define f first
#define s second
template<class T> using V = vector<T>;
using vi = V<int>;
using vb = V<bool>;
using vs = V<string>;
#define all(x) begin(x), end(x)
#define rall(x) rbegin(x), rend(x)
#define len(x) (int)((x).size())
#define rsz resize
#define ins insert
#define ft front()
#define bk back()
#define pb push_back
#define lb lower_bound
#define ub upper_bound
#define ai2 array<int,2>
#define ai3 array<int,3>
template<class T> int lwb(V<T>& a, const T& b) { return lb(all(a),b)-begin(a); }
template<class T> int upb(V<T>& a, const T& b) { return ub(all(a),b)-begin(a); }
template<class T> bool ckmin(T& a, const T& b) { return a > b ? a=b, true : false; }
template<class T> bool ckmax(T& a, const T& b) { return a < b ? a=b, true : false; }
#define pct __builtin_popcount
#define ctz __builtin_ctz
#define clz __builtin_clz
constexpr int p2(int x) { return (int)1 << x; }
constexpr int bits(int x) { return x == 0 ? 0 : 31-clz(x); } // floor(log2(x))
template<class T>void UNIQUE(V<T>& v) { sort(all(v)); v.erase(unique(all(v)),end(v)); }
template<class T,class U>void erase(T& t, const U& u) { auto it = t.find(u); assert(it != end(t)); t.erase(it); }
const int DEG=10;
V<vi>dp,g;
V<V<ai3>>transition_edges;
V<ai2>par;
const int LOG=10;
V<vi>lift;
vi dep;
void precalc(int u,int p){
int ind=0;
for(int v:g[u])if(v!=p){
dep[v]=dep[u]+1;
precalc(v,u);
lift[0][v]=u;
par[v]={u,p2(ind++)};
}
}
int lca(int u,int v){
if(dep[u]>dep[v])swap(u,v);
for(int i=LOG;i>=0;i--)if((dep[v]-dep[u])&p2(i))v=lift[i][v];
if(u==v)return u;
for(int i=LOG;i>=0;i--)if(lift[i][u]!=lift[i][v]){
u=lift[i][u];v=lift[i][v];
}
return lift[0][u];
}
int dist(int u,int v){
return dep[u]+dep[v]-2*dep[lca(u,v)];
}
void calc_dp(int u,int p){
for(int v:g[u])if(v!=p){
calc_dp(v,u);
dp[u][0]+=*max_element(all(dp[v]));
}
for(auto[a,b,w]:transition_edges[u]){
int score=0;
int maskA=0,maskB=0;
for(;a!=u;maskA=par[a][1],a=par[a][0]=par[a])score+=dp[a][maskA];
for(;b!=u;maskB=par[b][1],b=par[b][0]=par[b])score+=dp[b][maskB];
maskA|=maskB;
for(int msk=0;msk<p2(DEG);msk++){
if(msk&maskA)continue;
ckmax(dp[u][msk],score+dp[u][msk|maskA]+w);
}
}
}
void solve() {
int n,m;cin>>n>>m;
int sum_w=0;
V<ai3>edges;
g.rsz(n);
for(int i=0;i<m;i++){
int u,v,c;cin>>u>>v>>c;u--;v--;
edges.pb({u,v,c});
if(!c){
g[u].pb(v);g[v].pb(u);
}
sum_w+=c;
}
par.rsz(n);
lift.rsz(LOG+1,vi(n));
dep.rsz(n);
precalc(0,-1);
for(int i=1;i<=LOG;i++){
for(int u=0;u<n;u++){
lift[i][u]=lift[i-1][lift[i-1][u]];
}
}
transition_edges.rsz(n);
for(auto[u,v,c]:edges)if(c){
if(dist(u,v)&1)continue;
transition_edges[lca(u,v)].pb({u,v,c});
}
dp.rsz(n,vi(p2(DEG)));
calc_dp(0,-1);
cout<<sum_w-dp[0][0]<<'\n';
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
solve();
return 0;
}