File Annotation
Not logged in
143923277f 2014-11-03        kinaba: #include <iostream>
143923277f 2014-11-03        kinaba: #include <sstream>
143923277f 2014-11-03        kinaba: #include <iomanip>
143923277f 2014-11-03        kinaba: #include <vector>
143923277f 2014-11-03        kinaba: #include <string>
143923277f 2014-11-03        kinaba: #include <map>
143923277f 2014-11-03        kinaba: #include <set>
143923277f 2014-11-03        kinaba: #include <algorithm>
143923277f 2014-11-03        kinaba: #include <numeric>
143923277f 2014-11-03        kinaba: #include <iterator>
143923277f 2014-11-03        kinaba: #include <functional>
143923277f 2014-11-03        kinaba: #include <complex>
143923277f 2014-11-03        kinaba: #include <queue>
143923277f 2014-11-03        kinaba: #include <stack>
143923277f 2014-11-03        kinaba: #include <cmath>
143923277f 2014-11-03        kinaba: #include <cassert>
143923277f 2014-11-03        kinaba: #include <tuple>
143923277f 2014-11-03        kinaba: using namespace std;
143923277f 2014-11-03        kinaba: typedef long long LL;
143923277f 2014-11-03        kinaba: typedef complex<double> CMP;
143923277f 2014-11-03        kinaba: 
143923277f 2014-11-03        kinaba: const int INF = 0x1fffffff;
143923277f 2014-11-03        kinaba: 
143923277f 2014-11-03        kinaba: class CandleTimer { public:
143923277f 2014-11-03        kinaba: 	int differentTime(vector <int> A, vector <int> B, vector <int> len)
143923277f 2014-11-03        kinaba: 	{
143923277f 2014-11-03        kinaba: 		if(A.size() == 1) {
143923277f 2014-11-03        kinaba: 			// Special case, just in case. All nodes are leaves.
143923277f 2014-11-03        kinaba: 			// Either light only one end or both ends.
143923277f 2014-11-03        kinaba: 			return 2;
143923277f 2014-11-03        kinaba: 		}
143923277f 2014-11-03        kinaba: 
143923277f 2014-11-03        kinaba: 		// x2, to make all the possible final points on integer coordinates.
143923277f 2014-11-03        kinaba: 		for(auto& li: len)
143923277f 2014-11-03        kinaba: 			li *= 2;
143923277f 2014-11-03        kinaba: 
143923277f 2014-11-03        kinaba: 		// Prepare....
143923277f 2014-11-03        kinaba: 		const int E = A.size(), V = E+1;
143923277f 2014-11-03        kinaba: 
143923277f 2014-11-03        kinaba: 		vector<int> leaf;
143923277f 2014-11-03        kinaba: 		vector<bool> is_leaf(V, false);
143923277f 2014-11-03        kinaba: 		{
143923277f 2014-11-03        kinaba: 			vector<int> degree(V);
143923277f 2014-11-03        kinaba: 			for(auto a: A) degree[a]++;
143923277f 2014-11-03        kinaba: 			for(auto b: B) degree[b]++;
143923277f 2014-11-03        kinaba: 
143923277f 2014-11-03        kinaba: 			for(int v=0; v<V; ++v)
143923277f 2014-11-03        kinaba: 				if(degree[v]==1) {
143923277f 2014-11-03        kinaba: 					leaf.push_back(v);
143923277f 2014-11-03        kinaba: 					is_leaf[v] = true;
143923277f 2014-11-03        kinaba: 				}
143923277f 2014-11-03        kinaba: 		}
143923277f 2014-11-03        kinaba: 
143923277f 2014-11-03        kinaba: 		vector<vector<int>> dist(V, vector<int>(V, INF));
143923277f 2014-11-03        kinaba: 		{
143923277f 2014-11-03        kinaba: 			for(int i=0; i<V; ++i)
143923277f 2014-11-03        kinaba: 				dist[i][i] = 0;
143923277f 2014-11-03        kinaba: 			for(int i=0; i<E; ++i)
143923277f 2014-11-03        kinaba: 				dist[A[i]][B[i]] = dist[B[i]][A[i]] = len[i];
143923277f 2014-11-03        kinaba: 			for(int k=0; k<V; ++k)
143923277f 2014-11-03        kinaba: 			for(int i=0; i<V; ++i)
143923277f 2014-11-03        kinaba: 			for(int j=0; j<V; ++j)
143923277f 2014-11-03        kinaba: 				dist[i][j] = min(dist[i][j], dist[i][k]+dist[k][j]);
143923277f 2014-11-03        kinaba: 		}
143923277f 2014-11-03        kinaba: 
143923277f 2014-11-03        kinaba: 		vector<vector<pair<int,int>>> G(V); // len, dest
143923277f 2014-11-03        kinaba: 		for(int e=0; e<E; ++e) {
143923277f 2014-11-03        kinaba: 			G[A[e]].emplace_back(len[e], B[e]);
143923277f 2014-11-03        kinaba: 			G[B[e]].emplace_back(len[e], A[e]);
143923277f 2014-11-03        kinaba: 		}
143923277f 2014-11-03        kinaba: 
143923277f 2014-11-03        kinaba: 		// Compute all possible final points.
143923277f 2014-11-03        kinaba: 		enum {EID, POS};
143923277f 2014-11-03        kinaba: 		vector<tuple<int,int>> cand;
143923277f 2014-11-03        kinaba: 		{
143923277f 2014-11-03        kinaba: 			vector<bool> done(V, false);
143923277f 2014-11-03        kinaba: 
143923277f 2014-11-03        kinaba: 			// Add all leaves as the possible final point
143923277f 2014-11-03        kinaba: 			for(int e=0; e<E; ++e) {
143923277f 2014-11-03        kinaba: 				if(is_leaf[A[e]] && !done[A[e]])
143923277f 2014-11-03        kinaba: 					cand.emplace_back(e, 0), done[A[e]]=true;
143923277f 2014-11-03        kinaba: 				if(is_leaf[B[e]] && !done[B[e]])
143923277f 2014-11-03        kinaba: 					cand.emplace_back(e, len[e]), done[B[e]]=true;
143923277f 2014-11-03        kinaba: 			}
143923277f 2014-11-03        kinaba: 
143923277f 2014-11-03        kinaba: 			// Add all mid points.
143923277f 2014-11-03        kinaba: 			for(int la: leaf)
143923277f 2014-11-03        kinaba: 			for(int lb: leaf)
143923277f 2014-11-03        kinaba: 			for(int e=0; e<E; ++e)
143923277f 2014-11-03        kinaba: 			{
143923277f 2014-11-03        kinaba: 				int a=A[e], b=B[e], ll=len[e];
143923277f 2014-11-03        kinaba: 				if(dist[la][a]+ll+dist[lb][b] == dist[la][lb]) {
143923277f 2014-11-03        kinaba: 					if(abs(dist[la][a] - dist[lb][b]) <= ll) {
143923277f 2014-11-03        kinaba: 						tuple<int,int> c(e, (ll+dist[lb][b]-dist[la][a])/2);
143923277f 2014-11-03        kinaba: 						// TODO: reduce by done[]
143923277f 2014-11-03        kinaba: 						cand.push_back(c);
143923277f 2014-11-03        kinaba: 					}
143923277f 2014-11-03        kinaba: 				} else if(dist[la][b]+ll+dist[lb][a] == dist[la][lb]) {
143923277f 2014-11-03        kinaba: 					if(abs(dist[la][b] - dist[lb][a]) <= ll) {
143923277f 2014-11-03        kinaba: 						tuple<int,int> c(e, (ll+dist[la][b]-dist[lb][a])/2);
143923277f 2014-11-03        kinaba: 						// TODO: reduce by done[]
143923277f 2014-11-03        kinaba: 						cand.push_back(c);
143923277f 2014-11-03        kinaba: 					}
143923277f 2014-11-03        kinaba: 				}
143923277f 2014-11-03        kinaba: 			}
143923277f 2014-11-03        kinaba: 		}
143923277f 2014-11-03        kinaba: 
143923277f 2014-11-03        kinaba: 		// Distance between a candidate point and a node.
143923277f 2014-11-03        kinaba: 		function<int(tuple<int,int>,int)> calc_d = [&](tuple<int,int> c, int v) {
143923277f 2014-11-03        kinaba: 			return min(
143923277f 2014-11-03        kinaba: 				dist[A[get<EID>(c)]][v] + get<POS>(c),
143923277f 2014-11-03        kinaba: 				dist[B[get<EID>(c)]][v] + len[get<EID>(c)] - get<POS>(c)
143923277f 2014-11-03        kinaba: 			);
143923277f 2014-11-03        kinaba: 		};
143923277f 2014-11-03        kinaba: 
143923277f 2014-11-03        kinaba: 		// Simulate all.
143923277f 2014-11-03        kinaba: 		set<int> answer;
143923277f 2014-11-03        kinaba: 		for(auto c: cand)
143923277f 2014-11-03        kinaba: 		{
143923277f 2014-11-03        kinaba: 			vector<pair<int,int>> dist_leaf;
143923277f 2014-11-03        kinaba: 			for(int v: leaf)
143923277f 2014-11-03        kinaba: 				dist_leaf.emplace_back(calc_d(c, v), v);
143923277f 2014-11-03        kinaba: 			sort(dist_leaf.begin(), dist_leaf.end());
143923277f 2014-11-03        kinaba: 
143923277f 2014-11-03        kinaba: 			for(int i=0; i<dist_leaf.size(); ++i)
143923277f 2014-11-03        kinaba: 			{
143923277f 2014-11-03        kinaba: 				const int cand_time = dist_leaf[i].first;
143923277f 2014-11-03        kinaba: 				if(i>0 && cand_time == dist_leaf[i-1].first)
143923277f 2014-11-03        kinaba: 					continue;
143923277f 2014-11-03        kinaba: 
143923277f 2014-11-03        kinaba: 				// Light all leaves further or equal to dist_leaf[i].
143923277f 2014-11-03        kinaba: 				// Can the point |c| be the last point (burning at |cand_time|?)
143923277f 2014-11-03        kinaba: 
143923277f 2014-11-03        kinaba: 				// Dijkstra.
143923277f 2014-11-03        kinaba: 				vector<int> burn_time(V, INF);
143923277f 2014-11-03        kinaba: 				{
143923277f 2014-11-03        kinaba: 					priority_queue<pair<int,int>, vector<pair<int,int>>, greater<pair<int,int>>> Q;
143923277f 2014-11-03        kinaba: 					for(int k=i; k<dist_leaf.size(); ++k)
143923277f 2014-11-03        kinaba: 						Q.emplace(0, dist_leaf[k].second);
143923277f 2014-11-03        kinaba: 					while(!Q.empty()) {
143923277f 2014-11-03        kinaba: 						int d = Q.top().first;
143923277f 2014-11-03        kinaba: 						int v = Q.top().second;
143923277f 2014-11-03        kinaba: 						Q.pop();
143923277f 2014-11-03        kinaba: 						if(burn_time[v] != INF)
143923277f 2014-11-03        kinaba: 							continue;
143923277f 2014-11-03        kinaba: 						burn_time[v] = d;
143923277f 2014-11-03        kinaba: 						for(int i=0; i<G[v].size(); ++i)
143923277f 2014-11-03        kinaba: 						{
143923277f 2014-11-03        kinaba: 							int dd = G[v][i].first;
143923277f 2014-11-03        kinaba: 							int u = G[v][i].second;
143923277f 2014-11-03        kinaba: 							if(burn_time[u] == INF)
143923277f 2014-11-03        kinaba: 								Q.emplace(d+dd, u);
143923277f 2014-11-03        kinaba: 						}
143923277f 2014-11-03        kinaba: 					}
143923277f 2014-11-03        kinaba: 				}
143923277f 2014-11-03        kinaba: 
143923277f 2014-11-03        kinaba: 				int bt_min = INF;
143923277f 2014-11-03        kinaba: 				for(int e=0; e<E; ++e)
143923277f 2014-11-03        kinaba: 				{
143923277f 2014-11-03        kinaba: 					int a=A[e], b=B[e], ll=len[e], bt;
143923277f 2014-11-03        kinaba: 					if(burn_time[a]+ll == burn_time[b] || burn_time[b]+ll == burn_time[a]) {
143923277f 2014-11-03        kinaba: 						bt = max(burn_time[a], burn_time[b]);
143923277f 2014-11-03        kinaba: 					} else {
143923277f 2014-11-03        kinaba: 						bt = max(burn_time[a], burn_time[b]) + (ll -  abs(burn_time[b] - burn_time[a]))/2;
143923277f 2014-11-03        kinaba: 					}
143923277f 2014-11-03        kinaba: 					bt_min = min(bt_min, bt);
143923277f 2014-11-03        kinaba: 				}
143923277f 2014-11-03        kinaba: 
143923277f 2014-11-03        kinaba: 				if(bt_min >= cand_time)
143923277f 2014-11-03        kinaba: 					answer.insert(cand_time);
143923277f 2014-11-03        kinaba: 			}
143923277f 2014-11-03        kinaba: 		}
143923277f 2014-11-03        kinaba: 
143923277f 2014-11-03        kinaba: 		return answer.size();
143923277f 2014-11-03        kinaba: 	}
143923277f 2014-11-03        kinaba: };
143923277f 2014-11-03        kinaba: 
143923277f 2014-11-03        kinaba: // BEGIN CUT HERE
143923277f 2014-11-03        kinaba: #include <ctime>
143923277f 2014-11-03        kinaba: double start_time; string timer()
143923277f 2014-11-03        kinaba:  { ostringstream os; os << " (" << int((clock()-start_time)/CLOCKS_PER_SEC*1000) << " msec)"; return os.str(); }
143923277f 2014-11-03        kinaba: template<typename T> ostream& operator<<(ostream& os, const vector<T>& v)
143923277f 2014-11-03        kinaba:  { os << "{ ";
143923277f 2014-11-03        kinaba:    for(typename vector<T>::const_iterator it=v.begin(); it!=v.end(); ++it)
143923277f 2014-11-03        kinaba:    os << '\"' << *it << '\"' << (it+1==v.end() ? "" : ", "); os << " }"; return os; }
143923277f 2014-11-03        kinaba: void verify_case(const int& Expected, const int& Received) {
143923277f 2014-11-03        kinaba:  bool ok = (Expected == Received);
143923277f 2014-11-03        kinaba:  if(ok) cerr << "PASSED" << timer() << endl;  else { cerr << "FAILED" << timer() << endl;
143923277f 2014-11-03        kinaba:  cerr << "\to: \"" << Expected << '\"' << endl << "\tx: \"" << Received << '\"' << endl; } }
143923277f 2014-11-03        kinaba: #define CASE(N) {cerr << "Test Case #" << N << "..." << flush; start_time=clock();
143923277f 2014-11-03        kinaba: #define END	 verify_case(_, CandleTimer().differentTime(A, B, len));}
143923277f 2014-11-03        kinaba: int main(){
143923277f 2014-11-03        kinaba: 
143923277f 2014-11-03        kinaba: CASE(0)
143923277f 2014-11-03        kinaba: 	int A_[] = {0,1};
143923277f 2014-11-03        kinaba: 	  vector <int> A(A_, A_+sizeof(A_)/sizeof(*A_));
143923277f 2014-11-03        kinaba: 	int B_[] = {1,2};
143923277f 2014-11-03        kinaba: 	  vector <int> B(B_, B_+sizeof(B_)/sizeof(*B_));
143923277f 2014-11-03        kinaba: 	int len_[] = {10,1};
143923277f 2014-11-03        kinaba: 	  vector <int> len(len_, len_+sizeof(len_)/sizeof(*len_));
143923277f 2014-11-03        kinaba: 	int _ = 2;
143923277f 2014-11-03        kinaba: END
143923277f 2014-11-03        kinaba: CASE(1)
143923277f 2014-11-03        kinaba: 	int A_[] = {0,0,0};
143923277f 2014-11-03        kinaba: 	  vector <int> A(A_, A_+sizeof(A_)/sizeof(*A_));
143923277f 2014-11-03        kinaba: 	int B_[] = {1,2,3};
143923277f 2014-11-03        kinaba: 	  vector <int> B(B_, B_+sizeof(B_)/sizeof(*B_));
143923277f 2014-11-03        kinaba: 	int len_[] = {1,1,1};
143923277f 2014-11-03        kinaba: 	  vector <int> len(len_, len_+sizeof(len_)/sizeof(*len_));
143923277f 2014-11-03        kinaba: 	int _ = 2;
143923277f 2014-11-03        kinaba: END
143923277f 2014-11-03        kinaba: CASE(2)
143923277f 2014-11-03        kinaba: 	int A_[] = {0,0,0};
143923277f 2014-11-03        kinaba: 	  vector <int> A(A_, A_+sizeof(A_)/sizeof(*A_));
143923277f 2014-11-03        kinaba: 	int B_[] = {1,2,3};
143923277f 2014-11-03        kinaba: 	  vector <int> B(B_, B_+sizeof(B_)/sizeof(*B_));
143923277f 2014-11-03        kinaba: 	int len_[] = {1,2,3};
143923277f 2014-11-03        kinaba: 	  vector <int> len(len_, len_+sizeof(len_)/sizeof(*len_));
143923277f 2014-11-03        kinaba: 	int _ = 4;
143923277f 2014-11-03        kinaba: END
143923277f 2014-11-03        kinaba: CASE(3)
143923277f 2014-11-03        kinaba: 	int A_[] = {0,1,1,2,3,3,2,4};
143923277f 2014-11-03        kinaba: 	  vector <int> A(A_, A_+sizeof(A_)/sizeof(*A_));
143923277f 2014-11-03        kinaba: 	int B_[] = {1,2,3,4,5,6,7,8};
143923277f 2014-11-03        kinaba: 	  vector <int> B(B_, B_+sizeof(B_)/sizeof(*B_));
143923277f 2014-11-03        kinaba: 	int len_[] = {5,3,2,4,6,8,7,1};
143923277f 2014-11-03        kinaba: 	  vector <int> len(len_, len_+sizeof(len_)/sizeof(*len_));
143923277f 2014-11-03        kinaba: 	int _ = 7;
143923277f 2014-11-03        kinaba: END
143923277f 2014-11-03        kinaba: CASE(4)
143923277f 2014-11-03        kinaba: 	int A_[] = {0,0,0,0};
143923277f 2014-11-03        kinaba: 	  vector <int> A(A_, A_+sizeof(A_)/sizeof(*A_));
143923277f 2014-11-03        kinaba: 	int B_[] = {1,2,3,4};
143923277f 2014-11-03        kinaba: 	  vector <int> B(B_, B_+sizeof(B_)/sizeof(*B_));
143923277f 2014-11-03        kinaba: 	int len_[] = {123,456,789,1000};
143923277f 2014-11-03        kinaba: 	  vector <int> len(len_, len_+sizeof(len_)/sizeof(*len_));
143923277f 2014-11-03        kinaba: 	int _ = 8;
143923277f 2014-11-03        kinaba: END
143923277f 2014-11-03        kinaba: CASE(5)
143923277f 2014-11-03        kinaba: 	int A_[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30};
143923277f 2014-11-03        kinaba: 	  vector <int> A(A_, A_+sizeof(A_)/sizeof(*A_));
143923277f 2014-11-03        kinaba: 	int B_[] = {0,1,2,0,0,0,1,0,0,0,2,5,4,7,13,13,6,15,11,18,19,21,22,16,19,19,20,18,22,27};
143923277f 2014-11-03        kinaba: 	  vector <int> B(B_, B_+sizeof(B_)/sizeof(*B_));
143923277f 2014-11-03        kinaba: 	int len_[] = {59,58,147,169,34,14,150,55,156,151,130,109,124,15,100,1,156,16,38,97,99,132,150,18,27,91,110,127,15,105};
143923277f 2014-11-03        kinaba: 	  vector <int> len(len_, len_+sizeof(len_)/sizeof(*len_));
143923277f 2014-11-03        kinaba: 	int _ = 65;
143923277f 2014-11-03        kinaba: END
143923277f 2014-11-03        kinaba: CASE(6)
143923277f 2014-11-03        kinaba: 	int A_[] = {0};
143923277f 2014-11-03        kinaba: 	  vector <int> A(A_, A_+sizeof(A_)/sizeof(*A_));
143923277f 2014-11-03        kinaba: 	int B_[] = {1};
143923277f 2014-11-03        kinaba: 	  vector <int> B(B_, B_+sizeof(B_)/sizeof(*B_));
143923277f 2014-11-03        kinaba: 	int len_[] = {1000};
143923277f 2014-11-03        kinaba: 	  vector <int> len(len_, len_+sizeof(len_)/sizeof(*len_));
143923277f 2014-11-03        kinaba: 	int _ = 2;
143923277f 2014-11-03        kinaba: END
143923277f 2014-11-03        kinaba: /*
143923277f 2014-11-03        kinaba: CASE(7)
143923277f 2014-11-03        kinaba: 	int A_[] = ;
143923277f 2014-11-03        kinaba: 	  vector <int> A(A_, A_+sizeof(A_)/sizeof(*A_));
143923277f 2014-11-03        kinaba: 	int B_[] = ;
143923277f 2014-11-03        kinaba: 	  vector <int> B(B_, B_+sizeof(B_)/sizeof(*B_));
143923277f 2014-11-03        kinaba: 	int len_[] = ;
143923277f 2014-11-03        kinaba: 	  vector <int> len(len_, len_+sizeof(len_)/sizeof(*len_));
143923277f 2014-11-03        kinaba: 	int _ = ;
143923277f 2014-11-03        kinaba: END
143923277f 2014-11-03        kinaba: CASE(8)
143923277f 2014-11-03        kinaba: 	int A_[] = ;
143923277f 2014-11-03        kinaba: 	  vector <int> A(A_, A_+sizeof(A_)/sizeof(*A_));
143923277f 2014-11-03        kinaba: 	int B_[] = ;
143923277f 2014-11-03        kinaba: 	  vector <int> B(B_, B_+sizeof(B_)/sizeof(*B_));
143923277f 2014-11-03        kinaba: 	int len_[] = ;
143923277f 2014-11-03        kinaba: 	  vector <int> len(len_, len_+sizeof(len_)/sizeof(*len_));
143923277f 2014-11-03        kinaba: 	int _ = ;
143923277f 2014-11-03        kinaba: END
143923277f 2014-11-03        kinaba: */
143923277f 2014-11-03        kinaba: }
143923277f 2014-11-03        kinaba: // END CUT HERE