File Annotation
Not logged in
4fd800b3a8 2011-02-23        kinaba: 
4fd800b3a8 2011-02-23        kinaba: //-------------------------------------------------------------
4fd800b3a8 2011-02-23        kinaba: // (Minimum) Set Cover
4fd800b3a8 2011-02-23        kinaba: //   NP-complete
4fd800b3a8 2011-02-23        kinaba: //
4fd800b3a8 2011-02-23        kinaba: // Assumption: "mask" must be downward closerd,
4fd800b3a8 2011-02-23        kinaba: //   i.e., X subset Y & Y in mask => X in mask
4fd800b3a8 2011-02-23        kinaba: //
4fd800b3a8 2011-02-23        kinaba: // Verified by
4fd800b3a8 2011-02-23        kinaba: //   - Google Code Jam 09 Round2 C
4fd800b3a8 2011-02-23        kinaba: //     (The "Only" part never tested, in the test cases of
4fd800b3a8 2011-02-23        kinaba: //      the problem, that optimization had never used.
4fd800b3a8 2011-02-23        kinaba: //      Be careful to use that; to be on the safer side,
4fd800b3a8 2011-02-23        kinaba: //      consider using the <true,false> mode.)
4fd800b3a8 2011-02-23        kinaba: //-------------------------------------------------------------
4fd800b3a8 2011-02-23        kinaba: 
4fd800b3a8 2011-02-23        kinaba: int minCover_exhaustive( int goal, const set<int>& mask )
4fd800b3a8 2011-02-23        kinaba: {
4fd800b3a8 2011-02-23        kinaba: 	typedef int STATE;
4fd800b3a8 2011-02-23        kinaba: 
4fd800b3a8 2011-02-23        kinaba: 	vector<STATE> Q( 1, 0 );
4fd800b3a8 2011-02-23        kinaba: 	set<STATE> visited;
4fd800b3a8 2011-02-23        kinaba: 	for(int step=0; step<=mask.size(); ++step)
4fd800b3a8 2011-02-23        kinaba: 	{
4fd800b3a8 2011-02-23        kinaba: 		vector<STATE> Q2;
4fd800b3a8 2011-02-23        kinaba: 		for(int i=0; i<Q.size(); ++i)
4fd800b3a8 2011-02-23        kinaba: 		{
4fd800b3a8 2011-02-23        kinaba: 			STATE s = Q[i];
4fd800b3a8 2011-02-23        kinaba: 			if( s == goal )
4fd800b3a8 2011-02-23        kinaba: 				return step;
4fd800b3a8 2011-02-23        kinaba: 			for(set<int>::const_iterator it=mask.begin(); it!=mask.end(); ++it)
4fd800b3a8 2011-02-23        kinaba: 				if( !visited.count( s|*it ) )
4fd800b3a8 2011-02-23        kinaba: 				{
4fd800b3a8 2011-02-23        kinaba: 					visited.insert( s|*it );
4fd800b3a8 2011-02-23        kinaba: 					Q2.push_back( s|*it );
4fd800b3a8 2011-02-23        kinaba: 				}
4fd800b3a8 2011-02-23        kinaba: 		}
4fd800b3a8 2011-02-23        kinaba: 		Q.swap(Q2);
4fd800b3a8 2011-02-23        kinaba: 	}
4fd800b3a8 2011-02-23        kinaba: 	return -1;
4fd800b3a8 2011-02-23        kinaba: }
4fd800b3a8 2011-02-23        kinaba: 
4fd800b3a8 2011-02-23        kinaba: template<bool Subs, bool Only>
4fd800b3a8 2011-02-23        kinaba: int minCover( int goal, set<int> mask )
4fd800b3a8 2011-02-23        kinaba: {
4fd800b3a8 2011-02-23        kinaba: 	if( Subs )
4fd800b3a8 2011-02-23        kinaba: 		for(set<int>::iterator it=mask.begin(); it!=mask.end(); )
4fd800b3a8 2011-02-23        kinaba: 		{
4fd800b3a8 2011-02-23        kinaba: 			bool needed = true;
4fd800b3a8 2011-02-23        kinaba: 			for(int m=1; m<=goal; m<<=1)
4fd800b3a8 2011-02-23        kinaba: 				if( (goal&m) && !(*it&m) && mask.count(*it|m))
4fd800b3a8 2011-02-23        kinaba: 					{needed = false; break;}
4fd800b3a8 2011-02-23        kinaba: 
4fd800b3a8 2011-02-23        kinaba: 			if( needed )
4fd800b3a8 2011-02-23        kinaba: 				++it;
4fd800b3a8 2011-02-23        kinaba: 			else
4fd800b3a8 2011-02-23        kinaba: 				mask.erase(it++);
4fd800b3a8 2011-02-23        kinaba: 		}
4fd800b3a8 2011-02-23        kinaba: 
4fd800b3a8 2011-02-23        kinaba: 	if( Only )
4fd800b3a8 2011-02-23        kinaba: 		for(set<int>::iterator it=mask.begin(); it!=mask.end(); )
4fd800b3a8 2011-02-23        kinaba: 		{
4fd800b3a8 2011-02-23        kinaba: 			int onlyByMe = goal & *it;
4fd800b3a8 2011-02-23        kinaba: 			for(set<int>::iterator jt=mask.begin(); jt!=mask.end(); ++jt)
4fd800b3a8 2011-02-23        kinaba: 				onlyByMe &= ~*jt;
4fd800b3a8 2011-02-23        kinaba: 
4fd800b3a8 2011-02-23        kinaba: 			if( !onlyByMe )
4fd800b3a8 2011-02-23        kinaba: 				++it;
4fd800b3a8 2011-02-23        kinaba: 			else
4fd800b3a8 2011-02-23        kinaba: 				mask.erase(it++), goal &= ~onlyByMe;
4fd800b3a8 2011-02-23        kinaba: 		}
4fd800b3a8 2011-02-23        kinaba: 
4fd800b3a8 2011-02-23        kinaba: 	return minCover_exhaustive(goal, mask);
4fd800b3a8 2011-02-23        kinaba: }