Submission #59166

#TimeUsernameProblemLanguageResultExecution timeMemory
59166TadijaSebezSimurgh (IOI17_simurgh)C++11
100 / 100
503 ms30580 KiB
#include "simurgh.h" #include <stdio.h> #include <vector> #include <set> using namespace std; #define pb push_back #define mp make_pair const int N=505; const int M=N*N; //---------------------------// /* bool in[M]; int count_common_roads(vector<int> v) { int i,sol=0; for(i=0;i<v.size();i++) sol+=in[v[i]]; return sol; } */ //---------------------------// vector<int> T,E[N],R[N]; vector<pair<int,int> > edges; int get(int u, int e) { if(edges[e].first==u) return edges[e].second; return edges[e].first; } int m; bool was[N]; void init(){ for(int i=0;i<N;i++) was[i]=0;} void AddEdge(int u, int v, int e){ E[u].pb(e);E[v].pb(e);edges.pb(mp(u,v));R[u].pb(e);R[v].pb(e);} void DelEdge(int e) { #define E R int u=edges[e].first,i,j; for(j=0;j<E[u].size();j++) if(E[u][j]==e) break; for(i=j;i+1<E[u].size();i++) E[u][i]=E[u][i+1]; E[u].pop_back(); u=edges[e].second; for(j=0;j<E[u].size();j++) if(E[u][j]==e) break; for(i=j;i+1<E[u].size();i++) E[u][i]=E[u][i+1]; E[u].pop_back(); #undef E } int par[N],dep[N],ed[N]; bool mark[M],done[M]; void FindTree(int u) { was[u]=1;dep[u]=dep[par[u]]+1; for(int i=0;i<E[u].size();i++) { int e=E[u][i]; int v=get(u,e); if(!was[v]) ed[v]=e,par[v]=u,mark[e]=1,T.pb(e),FindTree(v); } } int LCA(int u, int v) { while(dep[u]>dep[v]) u=par[u]; while(dep[v]>dep[u]) v=par[v]; while(par[u]!=par[v]) u=par[u],v=par[v]; return v==u?v:par[v]; } pair<vector<int> ,vector<int> > Undone(int u, int v) { int lca=LCA(u,v); vector<int> sol,cycle; for(;u!=lca;u=par[u]) { cycle.pb(ed[u]); if(!done[ed[u]]) sol.pb(ed[u]); } u=v; for(;u!=lca;u=par[u]) { cycle.pb(ed[u]); if(!done[ed[u]]) sol.pb(ed[u]); } return mp(sol,cycle); } struct DSU { int p[N]; DSU(){ for(int i=0;i<N;i++) p[i]=i;} void init(){ for(int i=0;i<N;i++) p[i]=i;} int Find(int x){ return x==p[x]?x:p[x]=Find(p[x]);} void Union(int x, int y){ p[Find(x)]=Find(y);} void Union(pair<int,int> a){ Union(a.first,a.second);} bool Check(pair<int,int> a){ return Find(a.first)!=Find(a.second);} } DS; int val[M]; pair<vector<int> ,int> Extend(vector<int> v) { DS.init(); int i,sol=0; for(i=0;i<v.size();i++) DS.Union(edges[v[i]]); for(i=0;i<T.size();i++) if(DS.Check(edges[T[i]])) DS.Union(edges[T[i]]),v.pb(T[i]),sol+=val[T[i]]; return mp(v,sol); } int Forest(vector<int> v) { pair<vector<int> ,int> tmp=Extend(v); return count_common_roads(tmp.first)-tmp.second; } int Cycle(vector<int> v) { pair<vector<int> ,int> tmp=Extend(v); return count_common_roads(tmp.first); } int min(int a, int b){ return a>b?b:a;} int max(int a, int b){ return a>b?a:b;} vector<int> S; int deg[N]; vector<int> find_roads(int n, vector<int> u, vector<int> v) { int i,j,k; m=u.size(); for(i=0;i<m;i++) AddEdge(u[i]+1,v[i]+1,i); FindTree(1); int tsz=count_common_roads(T); for(i=0;i<m;i++) if(!mark[i]) { pair<vector<int> ,vector<int> > tmp=Undone(edges[i].first,edges[i].second); if(tmp.first.size()==0) continue; tmp.second.pb(i); tmp.first.pb(i); vector<int> ask,ans; int lo=n,hi=-1; for(j=0;j<tmp.first.size();j++) { ask.clear(); for(k=0;k<tmp.second.size();k++) { if(tmp.second[k]!=tmp.first[j]) ask.pb(tmp.second[k]); } ans.pb(Cycle(ask)); lo=min(lo,ans.back()); hi=max(hi,ans.back()); } if(lo==hi) { int one=-1,zero=-1; for(j=0;j<tmp.second.size();j++) if(done[tmp.second[j]]) { if(val[tmp.second[j]]) one=tmp.second[j]; else zero=tmp.second[j]; } if(zero==-1) lo--; else { if(one!=-1) { ask.clear(); for(k=0;k<tmp.second.size();k++) { if(tmp.second[k]!=one) ask.pb(tmp.second[k]); } int tree=Cycle(ask); lo=min(lo,tree); hi=max(hi,tree); } ask.clear(); for(k=0;k<tmp.second.size();k++) { if(tmp.second[k]!=zero) ask.pb(tmp.second[k]); } int tree=Cycle(ask); lo=min(lo,tree); hi=max(hi,tree); } } for(j=0;j<tmp.first.size();j++) { if(ans[j]==hi) { //printf("OUT: %i\n",tmp.first[j]); done[tmp.first[j]]=1; DelEdge(tmp.first[j]); } else { //printf("IN: %i\n",tmp.first[j]); done[tmp.first[j]]=1; DelEdge(tmp.first[j]); val[tmp.first[j]]=1; S.pb(tmp.first[j]); } } } for(i=0;i<T.size();i++) if(!done[T[i]]) { //printf("BRIDGE: %i\n",T[i]); done[T[i]]=1; val[T[i]]=1; S.pb(T[i]); DelEdge(T[i]); } for(i=1;i<=n;i++) deg[i]=Forest(R[i]); for(k=1;k<=n;k++) { for(i=1;i<=n;i++) { if(deg[i]==1) { //if(x==1) //{ //printf("%i %i:D\n",i-1,R[i].size()); vector<int> tmp,ask[2]; tmp=R[i]; while(tmp.size()>1) { ask[0].clear();ask[1].clear(); for(j=0;j<tmp.size();j++) ask[j&1].pb(tmp[j]); int x=Forest(ask[0]); if(x==1) tmp=ask[0]; else tmp=ask[1]; } //printf("LEAF: %i\n",tmp[0]); S.pb(tmp[0]); val[tmp[0]]=1; done[tmp[0]]=1; DelEdge(tmp[0]); deg[i]--; deg[get(i,tmp[0])]--; //} } } } return S; } //---------------------------// /* int main() { int n,m,i,x; vector<int> u,v; scanf("%i %i",&n,&m); u.resize(m);v.resize(m); for(i=0;i<m;i++) scanf("%i %i",&u[i],&v[i]); for(i=0;i<n-1;i++) scanf("%i",&x),in[x]=1; vector<int> sol=find_roads(n,u,v); for(i=0;i<sol.size();i++) printf("%i ",sol[i]);printf("\n"); return 0; } */

Compilation message (stderr)

simurgh.cpp: In function 'void DelEdge(int)':
simurgh.cpp:36:11: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  for(j=0;j<E[u].size();j++) if(E[u][j]==e) break;
          ~^~~~~~~~~~~~
simurgh.cpp:37:13: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  for(i=j;i+1<E[u].size();i++) E[u][i]=E[u][i+1];
          ~~~^~~~~~~~~~~~
simurgh.cpp:40:11: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  for(j=0;j<E[u].size();j++) if(E[u][j]==e) break;
          ~^~~~~~~~~~~~
simurgh.cpp:41:13: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  for(i=j;i+1<E[u].size();i++) E[u][i]=E[u][i+1];
          ~~~^~~~~~~~~~~~
simurgh.cpp: In function 'void FindTree(int)':
simurgh.cpp:50:15: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  for(int i=0;i<E[u].size();i++)
              ~^~~~~~~~~~~~
simurgh.cpp: In function 'std::pair<std::vector<int>, int> Extend(std::vector<int>)':
simurgh.cpp:96:11: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  for(i=0;i<v.size();i++) DS.Union(edges[v[i]]);
          ~^~~~~~~~~
simurgh.cpp:97:11: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  for(i=0;i<T.size();i++) if(DS.Check(edges[T[i]])) DS.Union(edges[T[i]]),v.pb(T[i]),sol+=val[T[i]];
          ~^~~~~~~~~
simurgh.cpp: In function 'std::vector<int> find_roads(int, std::vector<int>, std::vector<int>)':
simurgh.cpp:129:12: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   for(j=0;j<tmp.first.size();j++)
           ~^~~~~~~~~~~~~~~~~
simurgh.cpp:132:13: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
    for(k=0;k<tmp.second.size();k++)
            ~^~~~~~~~~~~~~~~~~~
simurgh.cpp:143:13: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
    for(j=0;j<tmp.second.size();j++) if(done[tmp.second[j]])
            ~^~~~~~~~~~~~~~~~~~
simurgh.cpp:154:15: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
      for(k=0;k<tmp.second.size();k++)
              ~^~~~~~~~~~~~~~~~~~
simurgh.cpp:163:14: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
     for(k=0;k<tmp.second.size();k++)
             ~^~~~~~~~~~~~~~~~~~
simurgh.cpp:172:12: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   for(j=0;j<tmp.first.size();j++)
           ~^~~~~~~~~~~~~~~~~
simurgh.cpp:190:11: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  for(i=0;i<T.size();i++) if(!done[T[i]])
          ~^~~~~~~~~
simurgh.cpp:213:16: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
       for(j=0;j<tmp.size();j++) ask[j&1].pb(tmp[j]);
               ~^~~~~~~~~~~
simurgh.cpp:120:6: warning: unused variable 'tsz' [-Wunused-variable]
  int tsz=count_common_roads(T);
      ^~~
#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...