Submission #33228

# Submission time Handle Problem Language Result Execution time Memory
33228 2017-10-23T04:02:45 Z model_code Simurgh (IOI17_simurgh) C++11
100 / 100
211 ms 7916 KB
/*
   	IOI 2017
	Problem: Finding Spanning Tree
	Author: PrinceOfPersia
	Subtask: 5
*/
#include <iostream>
#include <algorithm>
#include <set>
#include <vector>
#include <string>
#include <map>
#include <cmath>
#include <cstdio>
#include <cassert>
#include <cstring>
#include "simurgh.h"
using namespace std;
#define Foreach(i, c) for(__typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)
#define For(i,a,b) for(int (i)=(a);(i) < (b); ++(i))
#define rof(i,a,b) for(int (i)=(a);(i) > (b); --(i))
#define rep(i, c) for(auto &(i) : (c))
#define x first
#define y second
#define pb push_back
#define PB pop_back()
#define iOS ios_base::sync_with_stdio(false)
#define sqr(a) (((a) * (a)))
#define all(a) a.begin() , a.end()
#define error(x) cerr << #x << " = " << (x) <<endl
#define Error(a,b) cerr<<"( "<<#a<<" , "<<#b<<" ) = ( "<<(a)<<" , "<<(b)<<" )\n";
#define errop(a) cerr<<#a<<" = ( "<<((a).x)<<" , "<<((a).y)<<" )\n";
#define coud(a,b) cout<<fixed << setprecision((b)) << (a)
#define L(x) ((x)<<1)
#define R(x) (((x)<<1)+1)
#define umap unordered_map
#define double long double
typedef long long ll;
typedef pair<int,int>pii;
typedef vector<int> vi;
template <class T>  inline void smax(T &x,T y){ x = max((x), (y));}
template <class T>  inline void smin(T &x,T y){ x = min((x), (y));}
template <class T>	inline void sminmax(T &mn, T &mx, T x){smin(mn, x), smax(mx, x);}
const int maxn = 512, maxm = maxn * maxn / 2;
pii highest[maxn];
bool mark[maxn];
int h[maxn], ind[maxn][maxn], state[maxn], par[maxn], last_num[maxm], n, m, deg[maxn];
vi __edges_vec;
vi adj[maxn];
pii edges[maxm];
bool bit[maxm];
int _next_ = 1;
int _last_id[maxm];

vector<int> ANS;

inline void _renew(){
	vi __edges_new;
	rep(i, __edges_vec)	if(bit[i] && _last_id[i] != _next_)
		__edges_new.pb(i), _last_id[i] = _next_;
	++ _next_;
	__edges_vec = __edges_new;
}
inline int query(){
	_renew();
	int res =  count_common_roads(__edges_vec);
	if(res == n-1)
		ANS = __edges_vec;
	return res;
}
inline void toggle(int i){
	if(!bit[i]){
		bit[i] = true;
		__edges_vec.pb(i);
	}
	else
		bit[i] = false;
}
inline void reset(){
	while(!__edges_vec.empty()){
		int e = __edges_vec.back();
		__edges_vec.PB;
		bit[e] = false;
	}
}
inline void dfs(int v = 0, int p = -1){
	par[v] = p;
	mark[v] = true;
	highest[v] = {h[v], -1};
	rep(u, adj[v]){
		int e = ind[v][u];
		if(!mark[u]){
			h[u] = h[v] + 1;
			dfs(u, v);
			if(highest[v].x > highest[u].x)
				highest[v] = highest[u];
		}
		else if(highest[v].x > h[u] && u != p)
			highest[v] = {h[u], e};
	}
	if(~p)
		toggle(ind[v][p]);
}
inline void DFS(int v = 0){
	int p = par[v];
	rep(u, adj[v])	if(par[u] == v)	DFS(u);
	if(~p && state[v] == -1){
		if(highest[v].x > h[p]){
			state[v] = 1;
			return ;
		}
		int back_edge = highest[v].y;
		int x = edges[back_edge].x, y = edges[back_edge].y;
		if(h[x] > h[y])	swap(x, y);
		int back_edge_num = query();
		int mn = back_edge_num, mx = mn;
		int cur = y;
		int for_a_one = -1;
		toggle(back_edge);
		while(cur != x){
			if(state[cur] == -1 or for_a_one == -1){
				int cur_edge = ind[cur][par[cur]];
				toggle(cur_edge);
				last_num[cur_edge] = query();
				sminmax(mn, mx, last_num[cur_edge]);
				if(~state[cur])
					for_a_one = last_num[cur_edge] - (!state[cur]);
				toggle(cur_edge);
			}
			cur = par[cur];
		}
		toggle(back_edge);
		cur = y;
		while(cur != x){
			if(state[cur] == -1){
				int cur_edge = ind[cur][par[cur]];
				if(~for_a_one)
					state[cur] = last_num[cur_edge] == for_a_one;
				else if(mn == mx)
					state[cur] = 0;
				else
					state[cur] = last_num[cur_edge] == mn;
			}
			cur = par[cur];
		}
	}
}
vi tree, ans;
inline int root(int v){return par[v] < 0? v: par[v] = root(par[v]);}
inline bool merge(int ind){
	int x = edges[ind].x, y = edges[ind].y;
	x = root(x), y = root(y);
	if(x == y)	return false;
	toggle(ind);
	if(par[y] < par[x])	swap(x, y);
	par[x] += par[y];
	par[y] = x;
	return true;
}
inline int edge_state(int i){
	int x = edges[i].x, y = edges[i].y;
	if(h[x] > h[y])	swap(x, y);
	return state[y];
}
inline int query_for_forest(vi subset){
	reset();
	int sum = 0;
	memset(par, -1, sizeof par);
	rep(e, subset)
		merge(e);
	rep(e, tree)
		if(merge(e))
			sum += edge_state(e);
	return query() - sum;
}
inline void calc_deg(int v){
	vi subset;
	rep(u, adj[v])
		subset.pb(ind[v][u]);
	deg[v] = query_for_forest(subset);
}
inline void remove(int v){
	if(!deg[v] or mark[v])	return ;
	assert(deg[v] == 1);
	vi ed;
	rep(u, adj[v])	if(!mark[u])	ed.pb(ind[v][u]);
	int l = 0, r = ed.size() - 1;
	while(r > l){
		int mid = (l + r)/2;
		vi subset(ed.begin()+l, ed.begin()+mid+1);
		if(query_for_forest(subset))
			r = mid;
		else
			l = mid + 1;
	}
	int e = ed[l];
	int u = edges[e].x + edges[e].y - v;
	ans.pb(e);
	-- deg[u];
	mark[v] = true;
	if(deg[u] == 1)
		remove(u);
}
vi find_roads(int n, vi v, vi u){
	::n = n;
	::m = v.size();;
	memset(state, -1, sizeof state);
	memset(ind, -1, sizeof ind);
	For(i,0,m){
		edges[i] = {v[i], u[i]};
		ind[v[i]][u[i]] = ind[u[i]][v[i]] = i;
		adj[v[i]].pb(u[i]), adj[u[i]].pb(v[i]);
	}
	dfs();
	DFS();
	memset(mark, 0, sizeof mark);
	For(i,0,m)	if(bit[i])
		tree.pb(i);
	For(i,0,n)	calc_deg(i);
	For(i,0,n)	if(deg[i] == 1)	remove(i);
	query_for_forest(ans);
	return ANS;
}

Compilation message

simurgh.cpp: In function 'void _renew()':
simurgh.cpp:22:29: warning: unnecessary parentheses in declaration of 'i' [-Wparentheses]
   22 | #define rep(i, c) for(auto &(i) : (c))
      |                             ^
simurgh.cpp:59:2: note: in expansion of macro 'rep'
   59 |  rep(i, __edges_vec) if(bit[i] && _last_id[i] != _next_)
      |  ^~~
simurgh.cpp: In function 'void dfs(int, int)':
simurgh.cpp:22:29: warning: unnecessary parentheses in declaration of 'u' [-Wparentheses]
   22 | #define rep(i, c) for(auto &(i) : (c))
      |                             ^
simurgh.cpp:90:2: note: in expansion of macro 'rep'
   90 |  rep(u, adj[v]){
      |  ^~~
simurgh.cpp: In function 'void DFS(int)':
simurgh.cpp:22:29: warning: unnecessary parentheses in declaration of 'u' [-Wparentheses]
   22 | #define rep(i, c) for(auto &(i) : (c))
      |                             ^
simurgh.cpp:106:2: note: in expansion of macro 'rep'
  106 |  rep(u, adj[v]) if(par[u] == v) DFS(u);
      |  ^~~
simurgh.cpp: In function 'int query_for_forest(vi)':
simurgh.cpp:22:29: warning: unnecessary parentheses in declaration of 'e' [-Wparentheses]
   22 | #define rep(i, c) for(auto &(i) : (c))
      |                             ^
simurgh.cpp:169:2: note: in expansion of macro 'rep'
  169 |  rep(e, subset)
      |  ^~~
simurgh.cpp:22:29: warning: unnecessary parentheses in declaration of 'e' [-Wparentheses]
   22 | #define rep(i, c) for(auto &(i) : (c))
      |                             ^
simurgh.cpp:171:2: note: in expansion of macro 'rep'
  171 |  rep(e, tree)
      |  ^~~
simurgh.cpp: In function 'void calc_deg(int)':
simurgh.cpp:22:29: warning: unnecessary parentheses in declaration of 'u' [-Wparentheses]
   22 | #define rep(i, c) for(auto &(i) : (c))
      |                             ^
simurgh.cpp:178:2: note: in expansion of macro 'rep'
  178 |  rep(u, adj[v])
      |  ^~~
simurgh.cpp: In function 'void remove(int)':
simurgh.cpp:22:29: warning: unnecessary parentheses in declaration of 'u' [-Wparentheses]
   22 | #define rep(i, c) for(auto &(i) : (c))
      |                             ^
simurgh.cpp:186:2: note: in expansion of macro 'rep'
  186 |  rep(u, adj[v]) if(!mark[u]) ed.pb(ind[v][u]);
      |  ^~~
simurgh.cpp: In function 'vi find_roads(int, vi, vi)':
simurgh.cpp:20:28: warning: unnecessary parentheses in declaration of 'i' [-Wparentheses]
   20 | #define For(i,a,b) for(int (i)=(a);(i) < (b); ++(i))
      |                            ^
simurgh.cpp:209:2: note: in expansion of macro 'For'
  209 |  For(i,0,m){
      |  ^~~
simurgh.cpp:20:28: warning: unnecessary parentheses in declaration of 'i' [-Wparentheses]
   20 | #define For(i,a,b) for(int (i)=(a);(i) < (b); ++(i))
      |                            ^
simurgh.cpp:217:2: note: in expansion of macro 'For'
  217 |  For(i,0,m) if(bit[i])
      |  ^~~
simurgh.cpp:20:28: warning: unnecessary parentheses in declaration of 'i' [-Wparentheses]
   20 | #define For(i,a,b) for(int (i)=(a);(i) < (b); ++(i))
      |                            ^
simurgh.cpp:219:2: note: in expansion of macro 'For'
  219 |  For(i,0,n) calc_deg(i);
      |  ^~~
simurgh.cpp:20:28: warning: unnecessary parentheses in declaration of 'i' [-Wparentheses]
   20 | #define For(i,a,b) for(int (i)=(a);(i) < (b); ++(i))
      |                            ^
simurgh.cpp:220:2: note: in expansion of macro 'For'
  220 |  For(i,0,n) if(deg[i] == 1) remove(i);
      |  ^~~
# Verdict Execution time Memory Grader output
1 Correct 1 ms 1388 KB correct
2 Correct 1 ms 1388 KB correct
3 Correct 1 ms 1388 KB correct
4 Correct 1 ms 1388 KB correct
5 Correct 1 ms 1388 KB correct
6 Correct 1 ms 1388 KB correct
7 Correct 1 ms 1388 KB correct
8 Correct 1 ms 1388 KB correct
9 Correct 1 ms 1388 KB correct
10 Correct 1 ms 1388 KB correct
11 Correct 2 ms 1388 KB correct
12 Correct 1 ms 1388 KB correct
13 Correct 1 ms 1388 KB correct
# Verdict Execution time Memory Grader output
1 Correct 1 ms 1388 KB correct
2 Correct 1 ms 1388 KB correct
3 Correct 1 ms 1388 KB correct
4 Correct 1 ms 1388 KB correct
5 Correct 1 ms 1388 KB correct
6 Correct 1 ms 1388 KB correct
7 Correct 1 ms 1388 KB correct
8 Correct 1 ms 1388 KB correct
9 Correct 1 ms 1388 KB correct
10 Correct 1 ms 1388 KB correct
11 Correct 2 ms 1388 KB correct
12 Correct 1 ms 1388 KB correct
13 Correct 1 ms 1388 KB correct
14 Correct 3 ms 1388 KB correct
15 Correct 2 ms 1516 KB correct
16 Correct 3 ms 1388 KB correct
17 Correct 2 ms 1388 KB correct
18 Correct 2 ms 1388 KB correct
19 Correct 2 ms 1388 KB correct
20 Correct 2 ms 1388 KB correct
21 Correct 2 ms 1388 KB correct
22 Correct 2 ms 1388 KB correct
23 Correct 2 ms 1388 KB correct
24 Correct 3 ms 1388 KB correct
25 Correct 1 ms 1388 KB correct
26 Correct 2 ms 1388 KB correct
27 Correct 2 ms 1388 KB correct
28 Correct 2 ms 1388 KB correct
29 Correct 2 ms 1388 KB correct
30 Correct 2 ms 1388 KB correct
31 Correct 3 ms 1388 KB correct
32 Correct 2 ms 1388 KB correct
33 Correct 2 ms 1388 KB correct
# Verdict Execution time Memory Grader output
1 Correct 1 ms 1388 KB correct
2 Correct 1 ms 1388 KB correct
3 Correct 1 ms 1388 KB correct
4 Correct 1 ms 1388 KB correct
5 Correct 1 ms 1388 KB correct
6 Correct 1 ms 1388 KB correct
7 Correct 1 ms 1388 KB correct
8 Correct 1 ms 1388 KB correct
9 Correct 1 ms 1388 KB correct
10 Correct 1 ms 1388 KB correct
11 Correct 2 ms 1388 KB correct
12 Correct 1 ms 1388 KB correct
13 Correct 1 ms 1388 KB correct
14 Correct 3 ms 1388 KB correct
15 Correct 2 ms 1516 KB correct
16 Correct 3 ms 1388 KB correct
17 Correct 2 ms 1388 KB correct
18 Correct 2 ms 1388 KB correct
19 Correct 2 ms 1388 KB correct
20 Correct 2 ms 1388 KB correct
21 Correct 2 ms 1388 KB correct
22 Correct 2 ms 1388 KB correct
23 Correct 2 ms 1388 KB correct
24 Correct 3 ms 1388 KB correct
25 Correct 1 ms 1388 KB correct
26 Correct 2 ms 1388 KB correct
27 Correct 2 ms 1388 KB correct
28 Correct 2 ms 1388 KB correct
29 Correct 2 ms 1388 KB correct
30 Correct 2 ms 1388 KB correct
31 Correct 3 ms 1388 KB correct
32 Correct 2 ms 1388 KB correct
33 Correct 2 ms 1388 KB correct
34 Correct 38 ms 2796 KB correct
35 Correct 38 ms 2796 KB correct
36 Correct 40 ms 2412 KB correct
37 Correct 13 ms 1516 KB correct
38 Correct 38 ms 2796 KB correct
39 Correct 35 ms 2668 KB correct
40 Correct 33 ms 2412 KB correct
41 Correct 38 ms 2796 KB correct
42 Correct 39 ms 2816 KB correct
43 Correct 29 ms 2284 KB correct
44 Correct 26 ms 2028 KB correct
45 Correct 29 ms 2160 KB correct
46 Correct 25 ms 1900 KB correct
47 Correct 19 ms 1644 KB correct
48 Correct 9 ms 1388 KB correct
49 Correct 12 ms 1516 KB correct
50 Correct 19 ms 1644 KB correct
51 Correct 28 ms 2028 KB correct
52 Correct 27 ms 2028 KB correct
53 Correct 26 ms 1900 KB correct
54 Correct 29 ms 2284 KB correct
55 Correct 30 ms 2156 KB correct
56 Correct 29 ms 2156 KB correct
57 Correct 29 ms 2156 KB correct
# Verdict Execution time Memory Grader output
1 Correct 1 ms 1388 KB correct
2 Correct 1 ms 1388 KB correct
3 Correct 116 ms 5484 KB correct
4 Correct 183 ms 7148 KB correct
5 Correct 193 ms 7276 KB correct
6 Correct 187 ms 7148 KB correct
7 Correct 197 ms 7276 KB correct
8 Correct 188 ms 7300 KB correct
9 Correct 183 ms 7148 KB correct
10 Correct 192 ms 7532 KB correct
11 Correct 186 ms 7148 KB correct
12 Correct 189 ms 7916 KB correct
13 Correct 1 ms 1388 KB correct
14 Correct 211 ms 7232 KB correct
15 Correct 188 ms 7788 KB correct
# Verdict Execution time Memory Grader output
1 Correct 1 ms 1388 KB correct
2 Correct 1 ms 1388 KB correct
3 Correct 1 ms 1388 KB correct
4 Correct 1 ms 1388 KB correct
5 Correct 1 ms 1388 KB correct
6 Correct 1 ms 1388 KB correct
7 Correct 1 ms 1388 KB correct
8 Correct 1 ms 1388 KB correct
9 Correct 1 ms 1388 KB correct
10 Correct 1 ms 1388 KB correct
11 Correct 2 ms 1388 KB correct
12 Correct 1 ms 1388 KB correct
13 Correct 1 ms 1388 KB correct
14 Correct 3 ms 1388 KB correct
15 Correct 2 ms 1516 KB correct
16 Correct 3 ms 1388 KB correct
17 Correct 2 ms 1388 KB correct
18 Correct 2 ms 1388 KB correct
19 Correct 2 ms 1388 KB correct
20 Correct 2 ms 1388 KB correct
21 Correct 2 ms 1388 KB correct
22 Correct 2 ms 1388 KB correct
23 Correct 2 ms 1388 KB correct
24 Correct 3 ms 1388 KB correct
25 Correct 1 ms 1388 KB correct
26 Correct 2 ms 1388 KB correct
27 Correct 2 ms 1388 KB correct
28 Correct 2 ms 1388 KB correct
29 Correct 2 ms 1388 KB correct
30 Correct 2 ms 1388 KB correct
31 Correct 3 ms 1388 KB correct
32 Correct 2 ms 1388 KB correct
33 Correct 2 ms 1388 KB correct
34 Correct 38 ms 2796 KB correct
35 Correct 38 ms 2796 KB correct
36 Correct 40 ms 2412 KB correct
37 Correct 13 ms 1516 KB correct
38 Correct 38 ms 2796 KB correct
39 Correct 35 ms 2668 KB correct
40 Correct 33 ms 2412 KB correct
41 Correct 38 ms 2796 KB correct
42 Correct 39 ms 2816 KB correct
43 Correct 29 ms 2284 KB correct
44 Correct 26 ms 2028 KB correct
45 Correct 29 ms 2160 KB correct
46 Correct 25 ms 1900 KB correct
47 Correct 19 ms 1644 KB correct
48 Correct 9 ms 1388 KB correct
49 Correct 12 ms 1516 KB correct
50 Correct 19 ms 1644 KB correct
51 Correct 28 ms 2028 KB correct
52 Correct 27 ms 2028 KB correct
53 Correct 26 ms 1900 KB correct
54 Correct 29 ms 2284 KB correct
55 Correct 30 ms 2156 KB correct
56 Correct 29 ms 2156 KB correct
57 Correct 29 ms 2156 KB correct
58 Correct 1 ms 1388 KB correct
59 Correct 1 ms 1388 KB correct
60 Correct 116 ms 5484 KB correct
61 Correct 183 ms 7148 KB correct
62 Correct 193 ms 7276 KB correct
63 Correct 187 ms 7148 KB correct
64 Correct 197 ms 7276 KB correct
65 Correct 188 ms 7300 KB correct
66 Correct 183 ms 7148 KB correct
67 Correct 192 ms 7532 KB correct
68 Correct 186 ms 7148 KB correct
69 Correct 189 ms 7916 KB correct
70 Correct 1 ms 1388 KB correct
71 Correct 211 ms 7232 KB correct
72 Correct 188 ms 7788 KB correct
73 Correct 1 ms 1388 KB correct
74 Correct 184 ms 7260 KB correct
75 Correct 186 ms 7148 KB correct
76 Correct 98 ms 3820 KB correct
77 Correct 198 ms 7416 KB correct
78 Correct 185 ms 7404 KB correct
79 Correct 188 ms 7276 KB correct
80 Correct 183 ms 7020 KB correct
81 Correct 199 ms 6380 KB correct
82 Correct 190 ms 7148 KB correct
83 Correct 145 ms 4588 KB correct
84 Correct 147 ms 5100 KB correct
85 Correct 137 ms 4844 KB correct
86 Correct 120 ms 3820 KB correct
87 Correct 105 ms 3180 KB correct
88 Correct 98 ms 2668 KB correct
89 Correct 95 ms 2668 KB correct
90 Correct 92 ms 2412 KB correct
91 Correct 40 ms 1516 KB correct
92 Correct 28 ms 1516 KB correct
93 Correct 138 ms 5016 KB correct
94 Correct 118 ms 3840 KB correct
95 Correct 119 ms 3820 KB correct
96 Correct 93 ms 2540 KB correct
97 Correct 97 ms 2668 KB correct
98 Correct 105 ms 3180 KB correct
99 Correct 98 ms 2668 KB correct
100 Correct 63 ms 1900 KB correct
101 Correct 28 ms 1516 KB correct
102 Correct 138 ms 4332 KB correct
103 Correct 141 ms 4332 KB correct
104 Correct 149 ms 4332 KB correct
105 Correct 162 ms 4332 KB correct