제출 #283922

#제출 시각아이디문제언어결과실행 시간메모리
283922erd1Simurgh (IOI17_simurgh)C++14
100 / 100
293 ms7080 KiB
#include "simurgh.h" #include<bits/stdc++.h> using namespace std; #define pb push_back #define ff first #define ss second #define all(x) (x).begin(), (x).end() typedef pair<int, int> pii; typedef long long lld; typedef long double ld; template<typename Iter> ostream& outIt(ostream& out, Iter b, Iter e){ for(Iter i = b; i != e; ++i) out << (i == b?"":" ") << *i; return out; } template<typename T1, typename T2> ostream& operator<<(ostream& out, pair<T1, T2> p){ return out << '(' << p.ff << ", " << p.ss << ')'; } template<typename T> ostream& operator<<(ostream& out, vector<T> v){ return outIt(out << '[', all(v)) << ']'; } vector<vector<pii>> G; vector<bool> asked, ans; vector<int> te, es, dep, par, pe; vector<pii> Edges; //int c = 0; int dfs(int i, int d = 1){ //cout << i << " " << d << " " << par[i] << endl; //if(c++>100)exit(-1); dep[i] = d; int minup = d; for(auto x : G[i]){ if(x.ss == pe[i])continue; if(dep[x.ff]){ //cout << "counter" << x << endl; minup = min(minup, dep[x.ff]); continue; } es.pb(x.ss); te[x.ss] = es.size(); pe[x.ff] = x.ss; par[x.ff] = i; minup = min(minup, dfs(x.ff, d + 1)); } if(!i)return 0; //cout << i << minup << endl; if(minup == d){ ans[pe[i]] = true; asked[pe[i]] = true; } return minup; } int asking(int tree, int nontree){ //cout << "ask " << tree << " " << nontree << endl; swap(es[te[tree]-1], nontree); int ansx = count_common_roads(es); swap(es[te[tree]-1], nontree); //cout << ansx << endl; return ansx; } vector<int> dsu; int root(int i){ return i == dsu[i] ? i : (dsu[i] = root(dsu[i])); } inline bool join(int i, int j){ i = root(i), j = root(j); if(i == j)return false; dsu[i] = j; return true; } int ask2(vector<int>& v){ //cout << v << es << endl; iota(all(dsu), 0); int mm = v.size(), cnt = 0; for(auto i: v)assert(join(Edges[i].ff, Edges[i].ss)); //cout << "gh" << endl; for(auto i: es) if(join(Edges[i].ff, Edges[i].ss)) cnt += ans[i], v.pb(i); int ret = count_common_roads(v); v.resize(mm); return ret - cnt; } void process(int k){ vector<int> gt, a; for(auto x: G[k]) if(!asked[x.ss])gt.pb(x.ss); if(gt.size() == 0)return; int deg = ask2(gt); //cout << "process" << k << endl; //for(auto i: gt)cout << Edges[i]; cout << endl; //cout << deg << endl; for(int i = 0; i < deg; i++){ int l = 0, r = gt.size(); while(r-l > 1){ a.resize(0); for(int j = 0; j < (l+r>>1); j++)a.pb(gt[j]); (ask2(a) <= i?l:r) = l+r>>1; } ans[gt[l]] = true; } for(auto i: gt)asked[i] = true; //cout << asked << endl << ans << endl << endl; } vector<int> find_roads(int n, vector<int> u, vector<int> v) { int m = u.size(); te.resize(m); asked.resize(m); ans.resize(m); pe.resize(n); par.resize(n); dep.resize(n); pe[0] = -1; dsu.resize(n); G.resize(n); for(int i = 0; i < m; i++)Edges.pb({u[i], v[i]}); for(int i = 0; i < m; i++)G[u[i]].pb({v[i], i}), G[v[i]].pb({u[i], i}); dfs(0); int tans = count_common_roads(es); //cout << tans << endl; //cout << asked << endl; //cout << te << es << dep << par << endl; for(int i = 0; i < m; i++) if(dep[u[i]] < dep[v[i]])swap(u[i], v[i]); for(int i = 0; i < m; i++) if(!te[i]){ //cout << i << endl; int tt = -1, go = false; for(int c = u[i]; c != v[i]; c = par[c]){ if(asked[pe[c]])tt = pe[c]; else go = true; } if(!go)continue; if(tt != -1){ { int cans = asking(tt, i); if(cans == tans)ans[i] = ans[tt]; else if(cans < tans)ans[i] = false, assert(ans[tt] == true); else if(cans > tans)ans[i] = true, assert(ans[tt] == false); asked[i] = true; } for(int c = u[i]; c != v[i]; c = par[c]) if(!asked[pe[c]]){ int cans = asking(pe[c], i); if(cans == tans)ans[pe[c]] = ans[i]; else if(cans < tans)ans[pe[c]] = true; else if(cans > tans)ans[i] = true; asked[pe[c]] = true; } }else{ for(int c = u[i]; c != v[i]; c = par[c]) if(!asked[pe[c]]){ int cans = asking(pe[c], i); if(cans < tans)ans[pe[c]] = true; else if(cans > tans)ans[i] = true; if(cans != tans)asked[pe[c]] = asked[i] = true; } asked[i] = true; for(int c = u[i]; c != v[i]; c = par[c]) if(!asked[pe[c]]) ans[pe[c]] = ans[i], asked[pe[c]] = true; } } //cout << asked << endl << ans << endl; for(int i = 0; i < n; i++)process(i); //cout << asked << endl << ans << endl; vector<int> ret; for(int i = 0; i < m; i++){ assert(asked[i]); if(ans[i])ret.pb(i); } //assert(ret.size() == n-1); return ret; }

컴파일 시 표준 에러 (stderr) 메시지

simurgh.cpp: In function 'void process(int)':
simurgh.cpp:100:25: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  100 |    for(int j = 0; j < (l+r>>1); j++)a.pb(gt[j]);
      |                        ~^~
simurgh.cpp:101:26: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  101 |    (ask2(a) <= i?l:r) = l+r>>1;
      |                         ~^~
#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...