답안 #42842

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
42842 2018-03-04T19:32:48 Z alenam0161 Simurgh (IOI17_simurgh) C++14
13 / 100
125 ms 4632 KB
#include "simurgh.h"
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cassert>
using namespace std;
#define DG(x) for(int i=0;i<(x).size();++i)cerr<<x[i]<<", ";
const int N = 1e3 + 7;
int used[N];
struct edge {
	int ham, x;
};
vector<edge> g[N], ham[N],Nor[N];
void pr(vector<edge> Tp) {
	for (edge to : Tp) {
		cout << "h=" << to.ham << "and v=" << to.x << ", ";
	}
	cout << endl;
}
vector<int> V, U;
bool is_it_in_T[N*N],Found[N*N];
int arj[N],Q[N];
int How[N*N];
int di[N];
int n,m;
void get_any(int v, vector<int> &T) {
	used[v] = true;
	for (auto to:g[v]) {
		if (used[to.x])continue;
		di[to.x] = di[v] + 1;
		T.push_back(to.ham);
		is_it_in_T[to.ham] = true;
		get_any(to.x, T);
	}
}
int par[N];
int find_par(int v) {
	return (v == par[v] ? v : par[v] = find_par(par[v]));
}
void Merge(int v, int u) {
	v = find_par(v);
	u = find_par(u);
	if (u != v) {
		if (rand() & 1)par[v] = u;
		else par[u] = v;
	}
}
int Newspantree(vector<int> &cur,vector<int> &T) {
	for (int i = 0; i < n; ++i)par[i] = i;
	for (int i = 0; i < cur.size(); ++i)Merge(V[cur[i]], U[cur[i]]);
	int hw = 0;
	for (int i = 0; i < T.size(); ++i) {
		if (find_par(V[T[i]]) == find_par(U[T[i]]))continue;
		Merge(V[T[i]], U[T[i]]);
		cur.push_back(T[i]);
		hw+=Found[T[i]];
	}
	assert(cur.size() == n - 1);
	return hw;
}
vector<int> Cikl;
int curpar[N];
bool gta;
void find_cik(int v,int G,int p) {
	if (gta == false) {
		used[v] = 1;
		for (edge to : g[v]) {
			if (to.x == p)continue;
			if (gta)return;
			if (used[to.x] == 2)continue;
			if (is_it_in_T[to.ham] == false)continue;
			if (used[to.x] == 0) {
				curpar[to.x] = v;
				Cikl.push_back(to.ham);
				find_cik(to.x, G,v);
				if (gta)return;
				Cikl.pop_back();
			}
			else if (used[to.x] == 1 && to.x == G) {
				Cikl.push_back(to.ham);
				gta = true; return;
			}
		}
		if (gta)return;
		for (edge to : g[v]) {
			if (to.x == p)continue;
			if (used[to.x] == 2)continue;
			if (gta)return;
			if (is_it_in_T[to.ham] == true)continue;
			if (used[to.x] == 0) {
				curpar[to.x] = v;
				Cikl.push_back(to.ham);
				find_cik(to.x, G,v);
				if (gta)return;
				Cikl.pop_back();
			}
			else if (used[to.x] == 1 && to.x == G) {
				Cikl.push_back(to.ham);
				gta = true;return;
			}
		}
		used[v] = 2;
	}
}
std::vector<int> find_roads(int n, std::vector<int> u, std::vector<int> v) {
	::n = n; ::m = u.size();
	U = u; V = v;
	for (int i = 0; i < u.size(); ++i) {
		g[u[i]].push_back({ i,v[i] });
		g[v[i]].push_back({ i,u[i] });
	}
	vector<int> ans;
	vector<int> T;
	vector<int> val;
	memset(used, 0, sizeof(used));
	get_any(0, T);
	for (int i = 0; i < u.size(); ++i) {
		if (is_it_in_T[i] == true) {
			if (How[i])continue;
			How[i] = true;
			memset(used, 0, sizeof(used));
			Cikl.clear();
			gta = false;
			Cikl.push_back(i);
			used[(di[u[i]] <= di[v[i]] ? u[i] : v[i])] =1;
			find_cik((di[u[i]] >= di[v[i]] ? u[i] : v[i]),( di[u[i]] <= di[v[i]] ? u[i] : v[i]), (di[u[i]] <= di[v[i]] ? u[i] : v[i]));
			val.resize(Cikl.size(), 0);
			for (int ii = 0; ii < Cikl.size(); ++ii) {
				vector<int> cur;
				for (int j = 0; j < Cikl.size(); ++j) {
					if (ii != j)cur.push_back(Cikl[j]);
				}
				Newspantree(cur, T);
				val[ii] = count_common_roads(cur);
			}
			int mx = -1e9;int mn = 1e9;
			for (int ii = 0; ii < Cikl.size(); ++ii) {
				mx = max(mx, val[ii]);
				mn = min(mn, val[ii]);
				How[Cikl[ii]] = true;
			}
			if (mx == mn) {
				for (int ii = 0; ii < Cikl.size(); ++ii) {
					Found[Cikl[ii]] = 1;
				}
			}
			else {
				for (int ii = 0; ii < Cikl.size(); ++ii) {
					if(mn==val[ii])
					Found[Cikl[ii]] = 1;
					else 
					Found[Cikl[ii]] = 0;
				}
			}
		}
	}
	for (int i = 0; i < n; ++i) {
		vector<int> e;
		for (auto to : g[i])e.push_back(to.ham);
		int k=Newspantree(e, T);
		int gt = count_common_roads(e);
		arj[i] = gt - k;
		Q[i] = gt - k;
	}
	for (int i = 0; i < m; ++i) {
		if (Found[i] == 1) {
			Q[v[i]]--;
			arj[u[i]]--;
			Q[u[i]]--;
			arj[v[i]]--;
		}
	}
	for (int i = 0; i < n; ++i) {
	//	cout << arj[i] << " ans vertex=" << i << endl;
	}
	memset(used, 0, sizeof(used));
	for (int i = 0; i < n; ++i) {
		int ps = -1;
		for (int j = 0; j < n; ++j) {
			if (arj[j] == 1 && used[j] == 0) {
				ps = j; break;
			}
		}
		if (ps == -1)break;
		used[ps] = true;
		int hw = 0;
	//	cerr <<"vertex number:"<<i<<" is "<< ps << endl;
		int q = 0;
		for(edge to:g[ps]){
			if (How[to.ham] == true) {
				hw += Found[to.ham];
			}
			else {
				q++;
			}
		}
	//	cout << hw << " " << Q[ps] << endl;
		/*
		if (hw == Q[ps]) {
			for (edge to : g[ps]) {
				if (Found[to.ham] == 0 || How[to.ham] == 0)continue;
				arj[ps]--;
				arj[to.x]--;
			}
			continue;
		}
		*/
	//	cout << "mta" << endl;
	//	pr(g[ps]);
	//	cout << endl;
		int l = 0, r = q-1;
		int mid = l;
		int good = l;
		while (l <= r) {
			mid = (l + r) / 2;
			vector<int> el,er;
			int s = 0;
			int ok = 0;
			for (edge to : g[ps]) {
				if (How[to.ham] == true) {
					continue;
				}
				else {
					if (l <= s && s <= mid) {
						el.push_back(to.ham);
					}
					else if(mid+1<=s&&s<=r){
						er.push_back(to.ham);
					}
					s++;
				}
			}
			int x1=Newspantree(el, T);
			if (count_common_roads(el)-x1 == 1) {
				good = mid; r = mid-1;
			}
			else {
				 l = mid + 1;
			}
		}
		int s = 0;
		int ok = 0;
		for (edge to : g[ps]) {
			if (How[to.ham] == true) {
			}
			else {
				if (s==good) {
					arj[to.x]--;
					How[to.ham] = 1;
					Found[to.ham] = 1;
				}
				s++;
			}
		}
	}
	ans.clear();
	for (int i = 0; i < m; ++i) {
		if (Found[i] == 1)ans.push_back(i);
	}
//	DG(ans);
//	cout << endl;
	return ans;
}

Compilation message

simurgh.cpp: In function 'int Newspantree(std::vector<int>&, std::vector<int>&)':
simurgh.cpp:50:20: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  for (int i = 0; i < cur.size(); ++i)Merge(V[cur[i]], U[cur[i]]);
                    ^
simurgh.cpp:52:20: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  for (int i = 0; i < T.size(); ++i) {
                    ^
In file included from /usr/include/c++/5/cassert:43:0,
                 from simurgh.cpp:5:
simurgh.cpp:58:20: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  assert(cur.size() == n - 1);
                    ^
simurgh.cpp: In function 'std::vector<int> find_roads(int, std::vector<int>, std::vector<int>)':
simurgh.cpp:108:20: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  for (int i = 0; i < u.size(); ++i) {
                    ^
simurgh.cpp:117:20: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  for (int i = 0; i < u.size(); ++i) {
                    ^
simurgh.cpp:128:24: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
    for (int ii = 0; ii < Cikl.size(); ++ii) {
                        ^
simurgh.cpp:130:23: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
     for (int j = 0; j < Cikl.size(); ++j) {
                       ^
simurgh.cpp:137:24: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
    for (int ii = 0; ii < Cikl.size(); ++ii) {
                        ^
simurgh.cpp:143:25: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
     for (int ii = 0; ii < Cikl.size(); ++ii) {
                         ^
simurgh.cpp:148:25: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
     for (int ii = 0; ii < Cikl.size(); ++ii) {
                         ^
simurgh.cpp:218:8: warning: unused variable 'ok' [-Wunused-variable]
    int ok = 0;
        ^
simurgh.cpp:242:7: warning: unused variable 'ok' [-Wunused-variable]
   int ok = 0;
       ^
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 376 KB correct
2 Correct 2 ms 480 KB correct
3 Correct 1 ms 480 KB correct
4 Correct 1 ms 568 KB correct
5 Correct 1 ms 624 KB correct
6 Correct 1 ms 624 KB correct
7 Correct 1 ms 624 KB correct
8 Correct 1 ms 624 KB correct
9 Correct 1 ms 624 KB correct
10 Correct 2 ms 624 KB correct
11 Correct 1 ms 624 KB correct
12 Correct 1 ms 624 KB correct
13 Correct 1 ms 712 KB correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 376 KB correct
2 Correct 2 ms 480 KB correct
3 Correct 1 ms 480 KB correct
4 Correct 1 ms 568 KB correct
5 Correct 1 ms 624 KB correct
6 Correct 1 ms 624 KB correct
7 Correct 1 ms 624 KB correct
8 Correct 1 ms 624 KB correct
9 Correct 1 ms 624 KB correct
10 Correct 2 ms 624 KB correct
11 Correct 1 ms 624 KB correct
12 Correct 1 ms 624 KB correct
13 Correct 1 ms 712 KB correct
14 Incorrect 3 ms 748 KB WA in grader: NO
15 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 376 KB correct
2 Correct 2 ms 480 KB correct
3 Correct 1 ms 480 KB correct
4 Correct 1 ms 568 KB correct
5 Correct 1 ms 624 KB correct
6 Correct 1 ms 624 KB correct
7 Correct 1 ms 624 KB correct
8 Correct 1 ms 624 KB correct
9 Correct 1 ms 624 KB correct
10 Correct 2 ms 624 KB correct
11 Correct 1 ms 624 KB correct
12 Correct 1 ms 624 KB correct
13 Correct 1 ms 712 KB correct
14 Incorrect 3 ms 748 KB WA in grader: NO
15 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 748 KB correct
2 Correct 2 ms 748 KB correct
3 Incorrect 125 ms 4632 KB WA in grader: NO
4 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 376 KB correct
2 Correct 2 ms 480 KB correct
3 Correct 1 ms 480 KB correct
4 Correct 1 ms 568 KB correct
5 Correct 1 ms 624 KB correct
6 Correct 1 ms 624 KB correct
7 Correct 1 ms 624 KB correct
8 Correct 1 ms 624 KB correct
9 Correct 1 ms 624 KB correct
10 Correct 2 ms 624 KB correct
11 Correct 1 ms 624 KB correct
12 Correct 1 ms 624 KB correct
13 Correct 1 ms 712 KB correct
14 Incorrect 3 ms 748 KB WA in grader: NO
15 Halted 0 ms 0 KB -