結果
問題 | No.19 ステージの選択 |
ユーザー | beet |
提出日時 | 2019-04-06 20:02:14 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 3 ms / 5,000 ms |
コード長 | 4,085 bytes |
コンパイル時間 | 2,833 ms |
コンパイル使用メモリ | 215,988 KB |
実行使用メモリ | 5,376 KB |
最終ジャッジ日時 | 2024-06-24 19:57:17 |
合計ジャッジ時間 | 3,814 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge1 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
5,248 KB |
testcase_01 | AC | 2 ms
5,376 KB |
testcase_02 | AC | 2 ms
5,376 KB |
testcase_03 | AC | 3 ms
5,376 KB |
testcase_04 | AC | 2 ms
5,376 KB |
testcase_05 | AC | 2 ms
5,376 KB |
testcase_06 | AC | 2 ms
5,376 KB |
testcase_07 | AC | 2 ms
5,376 KB |
testcase_08 | AC | 2 ms
5,376 KB |
testcase_09 | AC | 2 ms
5,376 KB |
testcase_10 | AC | 2 ms
5,376 KB |
testcase_11 | AC | 2 ms
5,376 KB |
testcase_12 | AC | 2 ms
5,376 KB |
testcase_13 | AC | 3 ms
5,376 KB |
testcase_14 | AC | 2 ms
5,376 KB |
testcase_15 | AC | 2 ms
5,376 KB |
testcase_16 | AC | 2 ms
5,376 KB |
testcase_17 | AC | 2 ms
5,376 KB |
testcase_18 | AC | 2 ms
5,376 KB |
testcase_19 | AC | 2 ms
5,376 KB |
testcase_20 | AC | 2 ms
5,376 KB |
testcase_21 | AC | 3 ms
5,376 KB |
testcase_22 | AC | 2 ms
5,376 KB |
testcase_23 | AC | 2 ms
5,376 KB |
ソースコード
#include<bits/stdc++.h> using namespace std; using Int = long long; template<typename T1,typename T2> inline void chmin(T1 &a,T2 b){if(a>b) a=b;} template<typename T1,typename T2> inline void chmax(T1 &a,T2 b){if(a<b) a=b;} //Without merge technique struct UnionFind{ int n; vector<int> r,p; UnionFind(){} UnionFind(int sz):n(sz),r(sz,1),p(sz,0){iota(p.begin(),p.end(),0);} int find(int x){ return (x==p[x]?x:p[x]=find(p[x])); } bool same(int x,int y){ return find(x)==find(y); } void unite(int x,int y){ x=find(x);y=find(y); if(x==y) return; r[x]+=r[y]; p[y]=x; } }; template<typename T, typename E> struct SkewHeap{ using G = function<T(T,E)>; using H = function<E(E,E)>; using C = function<bool(T,T)>; G g; H h; C c; T INF; E ei; SkewHeap(G g,H h,C c,T INF,E ei):g(g),h(h),c(c),INF(INF),ei(ei){} struct Node{ Node *l,*r; T val; E add; Node(T val,E add):val(val),add(add){l=r=nullptr;} }; void eval(Node *a){ if(a==nullptr) return; if(a->add==ei) return; if(a->l) a->l->add=h(a->l->add,a->add); if(a->r) a->r->add=h(a->r->add,a->add); a->val=g(a->val,a->add); a->add=ei; } T top(Node *a){ return a!=nullptr?g(a->val,a->add):INF; } T snd(Node *a){ eval(a); return a!=nullptr?min(top(a->l),top(a->r)):INF; } Node* add(Node *a,E d){ if(a!=nullptr) a->add=h(a->add,d); return a; } Node* push(T v){ return new Node(v,ei); } Node* meld(Node *a,Node *b){ if(!a||!b) return a?a:b; if(c(top(a),top(b))) swap(a,b); eval(a); a->r=meld(a->r,b); swap(a->l,a->r); return a; } Node* pop(Node* a){ eval(a); auto res=meld(a->l,a->r); delete a; return res; } }; struct Precision{ Precision(){ cout<<fixed<<setprecision(1); } }precision_beet; //INSERT ABOVE HERE template<typename T> struct Arborescence{ typedef pair<T, int> P; using Heap = SkewHeap<P, T>; struct edge{ int from,to; T cost; edge(){} edge(int from,int to,T cost):from(from),to(to),cost(cost){} }; int n; P INF; UnionFind uf; vector<edge> edges; vector<typename Heap::Node*> come; vector<int> used,from; vector<T> cost; Arborescence(int n,T INF):n(n),INF(INF,-1),uf(n),come(n,NULL), used(n,0),from(n,-1),cost(n,-1){}; void add_edge(int from,int to,T cost){ edges.emplace_back(from,to,cost); } void input(int m,int offset=0){ for(int i=0;i<m;i++){ int u,v; T c; cin>>u>>v>>c; add_edge(u+offset,v+offset,c); } } T build(int r){ typename Heap::G g=[](P a,T b){return P(a.first+b,a.second);}; typename Heap::H h=[](T a,T b){return a+b;}; typename Heap::C c=[](P a,P b){return a>b;}; Heap heap(g,h,c,INF,0); used[r]=2; for(int i=0;i<(int)edges.size();i++){ edge &e=edges[i]; come[e.to]=heap.meld(come[e.to],heap.push(P(e.cost,i))); } T res=0; for(int i=0;i<n;i++){ if(used[i]) continue; int v=i; vector<int> l; while(used[v]!=2){ used[v]=1; l.emplace_back(v); if(!come[v]) return T(-1); from[v]=uf.find(edges[come[v]->val.second].from); cost[v]=heap.top(come[v]).first; come[v]=heap.pop(come[v]); if(from[v]==v) continue; res+=cost[v]; if(used[from[v]]==1){ int p=v; do{ if(come[p]!=nullptr) heap.add(come[p],-cost[p]); if(p!=v){ uf.unite(v,p); come[v]=heap.meld(come[v],come[p]); } p=uf.find(from[p]); }while(p!=v); }else{ v=from[v]; } } for(int u:l) used[u]=2; } return res; } }; //INSERT ABOVE HERE signed main(){ int n; cin>>n; const int INF = 1e6; Arborescence<int> G(n+1,INF); for(int i=0;i<n;i++){ int l,s; cin>>l>>s; s--; G.add_edge(s,i,l); G.add_edge(n,i,l*2); } int ans=G.build(n); cout<<(double)ans/2<<endl; return 0; }