This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#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 time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |