제출 #1052615

#제출 시각아이디문제언어결과실행 시간메모리
1052615handlenameTraining (IOI07_training)C++17
100 / 100
7 ms4700 KiB
#include <bits/stdc++.h> using namespace std; #define pb push_back #define mp make_pair #define float long double // const int MOD=1e9+7; const int MOD=998244353; const int sqn=450; const long double eps=1e-6; const int dx[4]={0,0,1,-1}; const int dy[4]={1,-1,0,0}; long long power(long long a,long long b,long long p=MOD){ long long res=1; while (b>0){ if (b%2==1) res=(res*a)%p; b/=2; a=(a*a)%p; } return res; } int n,m,sum; vector<int> adj[1001],children[1001]; vector<pair<pair<int,int>,int> > edges[1001]; int twok[1001][11],depth[1001],childid[1001]; void dfsfill(int x,int p,int dd){ twok[x][0]=p; depth[x]=dd; for (int i=1;i<11;i++){ if (twok[x][i-1]==-1) break; twok[x][i]=twok[twok[x][i-1]][i-1]; } int id=0; for (auto i:adj[x]){ if (i==p) continue; dfsfill(i,x,dd+1); children[x].pb(i); childid[i]=id; id++; } } int lcaa(int a,int b){ if (depth[a]<depth[b]) swap(a,b); int dd=depth[a]-depth[b]; for (int i=0;i<11;i++){ if (dd&(1<<i)){ a=twok[a][i]; } } if (a==b) return a; for (int i=10;i>=0;i--){ if (twok[a][i]!=twok[b][i]){ a=twok[a][i]; b=twok[b][i]; } } return twok[a][0]; } // start from graph containing only tree edges // add max weight nontree edges without even cycles // tree path of edge (A,B) consists of only tree edges // odd/even edges have odd/even length tree path // we can only take even edges // no 2 nontree edges can have tree path overlap // otherwise, odd path 1 + odd path 2 - overlap * 2 = even // hence, each tree edge is in max 1 odd cycle // we solve for every subtree // dp[index][mask] = max weight we can take // index = subtree root // mask = which of the root's children is removed // basically we have a tree // each nontree edge is like placing a weight on a path // we need to maximise the sum of weights without overlaps int dp[1001][1024]; void dfs(int x){ for (auto i:children[x]){ dfs(i); } int sz=children[x].size(); for (int i=0;i<(1<<sz);i++){ for (int j=0;j<sz;j++){ if (i&(1<<j)) continue; // since mask is who we want to exclude dp[x][i]+=dp[children[x][j]][0]; } } for (auto edge:edges[x]){ int a=edge.first.first; int b=edge.first.second; int cur=edge.second; int maska=0; while (a!=x){ cur+=dp[a][maska]; maska=(1<<childid[a]); a=twok[a][0]; } int maskb=0; while (b!=x){ cur+=dp[b][maskb]; maskb=(1<<childid[b]); b=twok[b][0]; } int mask=maska|maskb; for (int i=0;i<(1<<sz);i++){ if (i&mask) continue; dp[x][i]=max(dp[x][i],cur+dp[x][i|mask]); } } } void runtc(){ cin>>n>>m; for (int i=1;i<=m;i++){ int a,b,c; cin>>a>>b>>c; if (c==0){ adj[a].pb(b); adj[b].pb(a); } else { edges[0].pb(mp(mp(a,b),c)); } sum+=c; } dfsfill(1,-1,0); for (auto i:edges[0]){ int a=i.first.first; int b=i.first.second; int c=i.second; if ((depth[a]%2)!=(depth[b]%2)) continue; int lca=lcaa(a,b); edges[lca].pb(mp(mp(a,b),c)); } dfs(1); cout<<sum-dp[1][0]; } int main(){ ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); // freopen("movie.in","r",stdin); // freopen("movie.out","w",stdout); // freopen("input1.in","r",stdin); // freopen("output1.out","w",stdout); //freopen("tower_rush_input.txt","r",stdin); //freopen("hackercup_output.txt","w",stdout); int tcs; // cin>>tcs; tcs=1; for (int i=1;i<=tcs;i++){ // cout<<"Case #"<<i<<": "; runtc(); } }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...