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<bits/stdc++.h>
using namespace std;
#define ll long long
#define pb push_back
const int maxn = 5e2 + 20;
const int maxm = maxn * maxn + 20;
int from[maxm] , to[maxm] , par[maxn] , h[maxn] , is[maxm] , ed[maxm] , num;
vector<int> adj[maxn] , bc[maxn] , ind;
bool visited[maxn] , tree[maxm];
void plant(int v)
{
	visited[v] = 1;
	for(auto e : adj[v])
	{
		int u = from[e] ^ to[e] ^ v;
		if(!visited[u])
		{
			ind.pb(e);
			h[u] = h[v] + 1;
			par[u] = e;
			tree[e] = 1;
			plant(u);
		}
		else if(h[u] < h[v] - 1)
			bc[v].pb(e);
	}
}
vector<int> rem(vector<int> x , int y)
{
	vector<int> nw;
	for(auto k : x)
		if(k != y)
			nw.pb(k);
	return nw;
}
bool cmp(int x , int y)
{
	x = min(h[from[x]] , h[to[x]]);
	y = min(h[from[y]] , h[to[y]]);
	return x > y;
}
int wtf[maxm];
int get(vector<int> &bc , int sz)
{
	if(!sz)
		return 0;
	vector<int> shit;
	for(int i = 0; i < sz; i++)
	{
		int e = bc[i];
		tree[wtf[e]] = 0;
		shit.pb(e);
	}
	int ts = 0;
	for(auto x : ind)
		if(tree[x])
		{
			if(is[x] == 1)
				ts++;
			shit.pb(x);
		}
	for(int i = 0; i < sz; i++)
	{
		int e = bc[i];
		tree[wtf[e]] = 1;
	}
	return count_common_roads(shit) - ts;
}
void dfs(int v)
{
	for(auto e : adj[v])
	{
		int u = from[e] ^ to[e] ^ v;
		if(h[u] == h[v] + 1)
			dfs(u);
	}
	if(bc[v].empty())
		return;
	int last = v;
	sort(bc[v].begin() , bc[v].end() , cmp);
	for(auto e : bc[v])
	{
		while(!last);
		wtf[e] = par[last];
		last = from[e] ^ to[e] ^ v;
	}
	int k = bc[v].size() , st = 0 , stl = 0 , shit = get(bc[v] , k);
	while(k && shit > st)
	{
		int l = stl , r = k;
		while(r - l > 1)
		{
			int m = (l + r) / 2;
			if(get(bc[v] , m) > st)
				r = m;
			else
				l = m;
		}
		is[bc[v][r - 1]] = 1;
		stl = r;
		st++;
	}
}
vector<int> find_roads(int n,vector<int> A,vector<int> B)
{
	n = n;
	int m = A.size();
	for(int i = 0; i < m; i++)
	{
		int a = A[i] , b = B[i];
		adj[a].pb(i);
		adj[b].pb(i);
		from[i] = a , to[i] = b;
	}
	plant(0);
	memset(ed , -1 , sizeof ed);
	num = count_common_roads(ind);
	for(int i = 0; i < m; i++)
		if(!tree[i])
		{
			int v = from[i] , u = to[i];
			if(h[v] < h[u])
				swap(v , u);
			vector<int> ed;
			bool has0 = 0;
			while(v != u)
			{
				if(is[par[v]] == 0)
					has0 = 1;
				ed.pb(par[v]);
				v = from[par[v]] ^ to[par[v]] ^ v;
			}
			if(!has0)
				continue;
			vector<int> eq;
			for(auto e : ed)
			{
				if(is[e] != 0 && is[i] != 0)
					continue;
				ind = rem(ind , e);
				ind.pb(i);
				int nw = count_common_roads(ind);
				ind.pop_back() , ind.pb(e);
				if(nw == num)
				{
					if(is[e] != 0)
						is[i] = is[e];
					else
						eq.pb(e);
				}
				else if(nw == num + 1)
				{
					is[i] = 1;
					is[e] = -1;
				}
				else
				{
					is[e] = 1;
					is[i] = -1;
				}
			}
			if((int)eq.size() == (int)ed.size())
				is[i] = -1;
			for(auto e : eq)
				is[e] = is[i];
		}
	for(auto x : ind)
		if(is[x] == 0)
			is[x] = 1;
	dfs(0);
	vector<int> ans;
	for(int i = 0; i < m; i++)
	{
		if(!is[i])
			is[i] = -1;
		if(is[i] == 1)
			ans.pb(i);
	}
	while(count_common_roads(ans) != n - 1);
	return ans;
}
| # | 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... |