(挑战编程_8_4)Servicing Stations

http://www.programming-challenges.com/pg.php?page=downloadproblem&probid=110804&format=html

#include <iostream>
#include <cstdlib>
#include <vector>
#include <set>
#include <string>
#include <cstring>
#include <fstream>
#include <cassert>
#include <cmath>
#include <iomanip>

using namespace std;

//#define _MY_DEBUG_

const long long ONE = 1;

// 第i个station能到达的地方
long long station[36];
// 第i个之后所有的都不能到达的
long long last[36];


char buffer[65];


/*
	MainStructure: 主结构
*/
void MainStructure();

/*
	Process
*/
void Process();

/*
	回溯
*/
bool DFS(int vNum, int cur, long long state, int need, int step);

int main()
{
	MainStructure();
	return 0;
}


void MainStructure()
{
	
#ifdef _MY_DEBUG_
	string inputStr = "C:/Users/cao/Desktop/算法/要看的书/算法/2挑战编程/input/1.inp";
	//string inputStr = "D:/2挑战编程/input/110205.inp";
	string outputStr = "C:/Users/cao/Desktop/算法/要看的书/算法/2挑战编程/input/1.outp";
	ifstream fin;
	fin.open(inputStr);		

	cin.rdbuf(fin.rdbuf());	

	/*
	ofstream fout;
	fout.open(outputStr.c_str());
	cout.rdbuf(fout.rdbuf());
	*/

#endif

	Process();
			
}
void Process()
{
	//8 cout << sizeof(long long) << endl;
	int vNum, lNum;
	int v1, v2;
	while (cin >> vNum >> lNum)
	{
		if (vNum == 0 && lNum == 0)
		{
			break;
		}
		memset(station, 0, sizeof(station));


		//memset(last, 0, sizeof(station));
		// 首先设置自己到自己可达:第1个就将左移0位
		for (int i = 0; i < vNum; ++i)
		{

//itoa(ONE << i, buffer, 2);
//cout << buffer << endl;

			station[i + 1] |= (ONE << i);
		}
		for (int i = 0; i < lNum; ++i)
		{
			cin >> v1 >> v2;
			// 设置v1与v2之间可达
			station[v1] |= (ONE << (v2 - 1));
			station[v2] |= (ONE << (v1 - 1));			
		}

//for (int i = 1; i <= vNum; ++i)
//{
//	itoa(station[i], buffer, 2);
//	cout << buffer << endl;
//}


		last[vNum] = station[vNum];
		for (int i = vNum - 1; i > 0; --i)
		{
			last[i] = last[i + 1] | station[i];
		}

		if (lNum == 0)
		{
			cout << vNum << endl;
			continue;
		}

		// 这里的i表示个数
		for (int i = 1; i <= vNum; ++i)
		{
			long long state = 0;
			if (DFS(vNum, 1, state, i, 0))
			{
				cout << i << endl;
				break;
			}
		}
	}
}

bool DFS(int vNum, int cur, long long state, int need, int step)
{
	// 满足条件
	if (state == ((ONE << vNum) - 1))
	{
		return true;
	}

	// 如果搜完也没有结果
	if (step == need)
	{
		return false;
	}
	
	for (int i = cur; i <= vNum; ++i)
	{
		// 如果后面所有的都是station也不能满足条件,则直接剪枝跳过


//itoa(state, buffer, 2);
//cout << "state:" << buffer << endl;
//
//itoa((ONE << vNum) - 1, buffer, 2);
//cout << "answe:" << buffer << endl;
//
//itoa(last[i], buffer, 2);
//cout << "lasti:" << buffer << endl;
//
//itoa(station[i], buffer, 2);
//cout << "stati:" << buffer << endl;
//
//itoa(state | last[i], buffer, 2);
//cout << "left :" << buffer << endl;
//
//itoa(((ONE << vNum) - 1), buffer, 2);
//cout << "right:" << buffer << endl;
//cout << endl;

		if ((state | last[i]) != ((ONE << vNum) - 1))
		{
			return false;
		}
		if ((state | station[i]) == state)
		{
			continue;
		}
		if (DFS(vNum, i + 1, state | station[i], need, step + 1))
		{
			return true;
		}
	}
	return false;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值