华为2016某比赛初赛, 傻X做法不能看

突然600多阅读我慌了。。感觉浪费大家赞了……

题目是http://codecraft.huawei.com/       2016年初赛的题,类似TSP问题的那个……。


思路如下: 搜。

然后就傻乎乎搜炸了啊。。。


tarjan缩点后,DP剪枝去掉非法解(能去掉非常多的)。

结果依然是大数据出不了解。。。 所以我的方法非常烂啦


===================================

我们自以为很厉害的方法~实际上很垃圾,初赛20多分的样子,显然被刷啦~~~


但是毕竟做了。。代码保留一下就好了


往事不堪回首。。也不想读代码了。。直接看代码注释。。 这篇文章应该没人看吧…… 自己留纪念



#include "CheckMap.h"
#include <queue>
#include <ctime>
using namespace std;
//已经开启了using namespace std了

unsigned long long start = clock();
CheckMap check(1, 1);
unsigned short final_ans = 1000; //默认初始最小答案
unsigned short edge_ans[max_vertex_num] = {0}, edge_ans_size = 0;
unsigned short tmp_edge[max_vertex_num];
ImportantMap init_next[max_vertex_num], final_status;
//6|28|34|8|21|15|25|10|13|14|31
void dfs(Vertex current_vertex, ImportantMap current_map, unsigned short current_ans, unsigned short deep)
{
	if ( ((clock() - start) / (double)CLOCKS_PER_SEC) > 9.3)	return;
	if (current_ans >= final_status)	return;
	if (!check.check(current_vertex))	return; //查看这个节点是否能搜出来
	//cout << current_vertex << " " << current_map <<" " << current_ans << " " << deep << endl;
	if (current_vertex == check.end_vertex)//已经搜到终点啦
	{
		//因为有确保性原因,所以一定已经是解了?! 这个一会儿需要检测一下正确性

		if (((current_map & final_status) == final_status) && current_ans < final_ans)
		{
			//cout << current_vertex << " " << current_map <<" " << current_ans << " " << deep << endl;
			final_ans = current_ans;
			edge_ans_size = deep;
			memmove(edge_ans, tmp_edge, sizeof(short) * deep);
			cout << final_ans << endl;
			//for (int i = 0; i != edge_ans_size; ++ i)
			//	cout << edge_ans[i]<<" ";	cout << endl;

		}
		return;
	}
	vis[current_vertex] = true; //访问标记
	for (int i = 0; i != check.g[current_vertex].size(); ++ i)
	{
		Vertex will_vertex = check.g[current_vertex][i];
		//cout << will_vertex << endl;
		if (vis[will_vertex])	continue;//显然,已经访问过的,就不用访问
		//cout << current_map <<" " << init_next[will_vertex]<<" " << final_status << endl;
		if (((current_map | init_next[will_vertex]) & final_status) != final_status)	continue;
		tmp_edge[deep] = check.getEdgeNum(current_vertex , will_vertex);
		if (will_vertex <= check.total_importan_vertex)
		{
			dfs(	will_vertex, 
					current_map | (1<<(will_vertex - 1)), 
					current_ans + check.getDistance(current_vertex, will_vertex), 
					deep + 1);	
		}
		else 			dfs(	will_vertex, 
					current_map,//只保存访问过的重要点地图 
					current_ans + check.getDistance(current_vertex, will_vertex), 
					deep + 1);	
	}
	vis[current_vertex] = false;
}

void init()
{
	freopen("input.txt", "r", stdin);
	int n, m;
	cin >> n >> m;//点总数,边总数
	for (int i = 0; i != m; ++ i)
	{
		unsigned short a, b, c, d;
		cin >> a >> b >> c >> d;
		check.insert(b, c, d, a); //b->c 距离是d,编号是a
	}
	unsigned short zhongyaodian;
	cin >> zhongyaodian;


	/*
	 * Init
	 * 把Map.h里的部分元素,进行清理。
	 * 修改起点, 终点,重要点的总量, 所有点的总量这4个参数
	 * */
	check.setEndVertex(zhongyaodian); //设置重要的点的总量(终点)
	check.setTotalVertex(n); //设置总的点的数量
	check.setTotalImportanVertex(zhongyaodian); //设置重要点的总量
	final_status = (1 << zhongyaodian) - 1;//全部访问完的状态

	check.check(1);
	for (int i = 1; i <= check.total_vertex; ++ i)
		init_next[i] = check.f[check.belong[i]];
}

int main()
{
	init();

	//cout << final_status << endl;
	dfs(1, 1, 0, 0);
	for (int i = 0; i != edge_ans_size; ++ i)
		cout << edge_ans[i]<<" ";	cout << endl;
	


	cout <<"this program runing-time is: "<< ((clock() - start) / (double)CLOCKS_PER_SEC) << " s, and the final distance is " <<final_ans<< endl;
	//cout <<"this program runs: "<< start/1000.0 - clock()/1000.0 << "ms" << endl;

	return 0;
}


checkmap.h

#include "Map.h"

bool vis[max_vertex_num];


class CheckMap:public Map  //生成一个Check变量,来完成所有的check操作
{
	public:

	unsigned short belong[max_vertex_num]; //原来每个点,所属的连通块
	ImportantMap f[max_vertex_num];//f[i]表示i后继能到的点,包括自己

	CheckMap(Vertex start, Vertex end):Map(start, end)
	{
		memset(vis, false, sizeof(vis));
		clear();
	}	

	void clear() //清理tarjan和BFS运算所需要的数组元素
	{
		memset(DFN, 0, sizeof(DFN));
		memset(LOW, 0, sizeof(LOW));
		memset(instack, 0, sizeof(instack));
		memset(my_stack, 0, sizeof(my_stack));
		memset(f, 0, sizeof(f));
		memset(f_self, 0, sizeof(f_self));
		memset(belong, 0, sizeof(belong));
		memset(f_vis, false, sizeof(f_vis));//点是否被访问过,每个点只会被访问一次。(讲道理是这样)
		Stop = din = count = 0;
	}

	
	void tarjan(Vertex current_vertex)
	{
		//cout << current_vertex << endl;
		LOW[current_vertex] = DFN[current_vertex] = ++ din;
		my_stack[++ Stop] = current_vertex;
		instack[current_vertex] = true;
		for (int i = 0; i != g[current_vertex].size(); ++ i)
		{
			Vertex will_vertex = g[current_vertex][i];
			if (vis[will_vertex])	continue;//这个点已经在地图中被移除了
			if (!DFN[will_vertex])
			{
				tarjan(will_vertex);
				LOW[current_vertex] = min(LOW[current_vertex], LOW[will_vertex]);
			}
			else if (instack[will_vertex])	LOW[current_vertex] = min(LOW[current_vertex], DFN[will_vertex]);
		}
		if (LOW[current_vertex] == DFN[current_vertex])
		{
			Vertex tmp;
			++count;
			do
			{
				tmp = my_stack[Stop --];
				instack[tmp] = false;
				belong[tmp] = count;
				if (tmp <= total_importan_vertex)//属于重要点的范畴
				{
					f[count] |= 1 << (tmp - 1); //f[count]这个连通块多了一些元素
				}
			}while (tmp != current_vertex);
		}
	}

	//版本0.01的getF,看看能不能成功
	ImportantMap getF(Vertex current_vertex)
	{
		if (f_vis[current_vertex] == true)	return f[current_vertex];
		f_vis[current_vertex] = true;	//访问标记
		if (current_vertex == belong[end_vertex])//如果已经到了end_vertex,那么显然不能走动了
		{
			return f[belong[end_vertex]];
		}
		for (int i = 0; i != new_g[current_vertex].size(); ++ i)
		{
			f[current_vertex] |= getF(new_g[current_vertex][i]);
		}
		return f[current_vertex];
	}

	bool findWay(Vertex current_vertex)//连通块,查看是否有解
	{
		if (DFN[current_vertex] != DFN[0])	return DFN[current_vertex];
		if (current_vertex == belong[end_vertex])
		{
			if (f[current_vertex] == f[belong[end_vertex]])	
			{
				return DFN[current_vertex] = true;
			}
			return false;
			//如果到达最重点,并且最重点能遍历的情况,和当前情况相同则为true
		}
		for (int i = 0; i != new_g[current_vertex].size(); ++ i)
		{
			Vertex will_vertex = new_g[current_vertex][i];
			if (current_vertex == will_vertex)	continue;//自己到自己就有环了。。不能这样
//			cout << current_vertex <<" " << will_vertex << endl;
			if (f[will_vertex] == (f[current_vertex] ^ f_self[current_vertex]))
			{
				if (findWay(will_vertex))	
				{
					return DFN[current_vertex] = true;
				}
			}
		}
		return DFN[current_vertex] = false;
	}

	bool check(Vertex current_vertex)//判断当前是否合法
	{
		//if (current_vertex == 4)	cout<<"!!!!!"<<endl;
		clear(); //先清空所有数组元素

		for (int i = 1; i <= total_vertex; i ++)
		{
			if (!vis[i] &&  !DFN[i])	tarjan(i);//缩点
		}

		for (int i = 1; i <= count; ++ i)	new_g[i].clear();
		for (int i = 1; i <= total_vertex; i ++)//重新构图,顶点标号从1~total_vertex开始
		{
			if (vis[i])	continue;//出发点不合法
			for (int j = 0; j != g[i].size(); ++ j)
			{
				if (vis[g[i][j]] || belong[i] == belong[j])	continue;
				new_g[belong[i]].push_back(belong[g[i][j]]);
			}
		}

		memmove(f_self, f, sizeof(f_self)); //f_self全部是都是每个点自己的状态
		getF(belong[current_vertex]);//做一个DP,得到f数组

		/*这个地方有一个优化!
		 * 一开始预处理所有的子节点情况,如果不合法可以直接退出,得出情况
		 * 第一个点的后继,是否已经是全部未访问节点!
		*/
		memset(DFN, 120, sizeof(DFN)); //清理DFN数组,用来给findWay用
		return findWay(belong[current_vertex]);
		//备忘: 是否用bool就可以完成check
	}

	private:
	unsigned short DFN[max_vertex_num];  //时间戳
	unsigned short LOW[max_vertex_num]; //最早追溯到的时间戳
	bool instack[max_vertex_num]; // 顶点是否属于栈
	unsigned short my_stack[max_vertex_num]; //手写的一个简单的栈
	unsigned short Stop, din, count;//栈顶编号0~?, 时间戳编号1~?, 缩点后,每个连通块的编号1~?
	bool f_vis[max_vertex_num];
	ImportantMap f_self[max_vertex_num]; //f_self[i]表示i这个连通块里自己所拥有的重要的点

	vector<Vertex> new_g[max_vertex_num]; //缩点后的新图,路径不包含非法点
};//起点和终点都是1 需要后来修改



map.h


#include "preInclude.h"

class Map
{

	public:
	vector<short> g[max_vertex_num]; //邻接表
	unsigned short total_vertex; //最大的顶点标号,所有点的标号为1~total_vertex, 前面1~total_importan_vertex为重要点,其中1为起点,total_importan_vertex为终点
	unsigned short total_importan_vertex; //全部重要点的数量
	Vertex start_vertex; //起点标号。  一般为1
	Vertex end_vertex;   //终点标号, 一边为重要点的总数。


	void setTotalVertex(short total_vertex) //修改最大顶点标号
	{
		this -> total_vertex = total_vertex;
	}

	inline void setTotalImportanVertex(unsigned short total_importan_vertex) //修改重要的点最大点标号
	{
		this -> total_importan_vertex = total_importan_vertex;
	}

	inline void insert(Vertex arg0, Vertex arg1, unsigned short distance, unsigned short edge_num)
		//arg0 -> arg1 距离是distance ,边的标号是edge_num
	{
		if (this -> distance[arg0][arg1] > distance)
		{
			g[arg0].push_back(arg1);
			this -> distance[arg0][arg1] = distance;
			this -> edge_num[arg0][arg1] = edge_num;		
		}else
		{
			//do nothing	
		}
	}

	inline void setStartVertex(Vertex start_vertex)//修改起点标号
	{
		this -> start_vertex = start_vertex;
	}

	inline void setEndVertex(Vertex end_vertex)//修改终点标号
	{
		this -> end_vertex = end_vertex;
	}

	inline bool isConnected(Vertex arg0, Vertex arg1) //判断arg0和arg1是否连通
	{
		return edge_num[arg0][arg1] != null_distance;
	}

	inline unsigned short getDistance(Vertex arg0, Vertex arg1)// arg0->arg1的距离
	{
		return distance[arg0][arg1];
	}
	inline unsigned short getEdgeNum(Vertex arg0, Vertex arg1)//得到arg0->arg1的边
	{
		return edge_num[arg0][arg1];
	
	}


	Map(Vertex start, Vertex end):
		start_vertex(start),end_vertex(end),
		null_edge_num(56789),null_distance(56789) //构造函数,清空所有的变量
	{
		total_vertex = 0; //所有的顶点的数量为0,
		for (int i = 0; i != max_vertex_num; i ++)
		{
			g[i].reserve(10);
			for (int j = 0; j != max_vertex_num; j ++)
			{
				distance[i][j] = null_distance;
				edge_num[i][j] = null_edge_num;
			}
		}
	}

	private:
	unsigned short distance[max_vertex_num][max_vertex_num]; //距离矩阵
	unsigned short edge_num[max_vertex_num][max_vertex_num]; //边标号矩阵,只记录最小的边标号
	const unsigned short null_edge_num;
	const unsigned short null_distance;
};



preinclude.h


#include <iostream>
#include <cstdio>
#include <ctime>
#include <cstring>
#include <bitset>
#include <cstdlib>
#include <vector>
#include <algorithm>
using namespace std;

const int max_vertex_num = 610;
typedef unsigned short StatusVertex;
typedef unsigned short Vertex;
typedef bitset<max_vertex_num> BitSetMap;
typedef unsigned short Evaluation;
typedef unsigned long long ImportantMap;//二进制表示一个被遍历过的重要的点的信息,如果没遍历到就-1

a0001.cpp

#include <iostream>
#include <cstdio>
#include <ctime>
#include <cstring>
#include <bitset>
#include <cstdlib>
#include <vector>
using namespace std;

const int max_vertex_num = 610;
const int null_num = 56789;

typedef unsigned short StatusVertex;
typedef unsigned short Vertex;
typedef bitset<max_vertex_num> BitSetMap;
typedef unsigned short Evaluation;
typedef unsigned long long ImportantMap;//二进制表示一个被遍历过的重要的点的信息,如果没遍历到就-1
bool is_important_vertex[max_vertex_num]={0}; //is_important_vertex[i]==true表示i是否是重要点


class Status
{
	public:
	inline BitSetMap getBitSetMap() //返回当前地图
	{
		return traversed_map;
	}
	inline Vertex getCurrentVertex()//返回当前地图所停留的顶点
	{
		return current_vertex;
	}
	inline long getEvaluation() //返回估价值
	{
		return evaluation;
	}
	inline bool operator < (Status arg0)	const
	{
		return evaluation < arg0.evaluation;
	}
	inline void setEvaluation(unsigned short evaluation)
	{
		this -> evaluation = evaluation;
	}
	inline bool isVisited(Vertex arg0)//arg0是否被访问过了
	{
		return traversed_map[arg0];
	}
	inline bool isAccessible(Vertex arg0)//arg0是否可以访问
	{
		return traversed_map[arg0] == 0;
	}

	Status()
	{
		current_ans = 0;
		traversed_map =0;
		evaluation =0;
		current_vertex = 0;
		traversed_important_vertexs = 0;
		traversed_all_vertexs = 0;
	}

	private:
	BitSetMap	traversed_map;   //保存整个地图的状态。 00001表示1号点被访问过了,00011 表示1,2都被访问过了。
	Vertex current_vertex;  //当前状态停留的顶点
	unsigned short evaluation;  //整个状态的估价值
	unsigned short traversed_all_vertexs; //所有遍历过的点的数量
	unsigned short traversed_important_vertexs; //所有被遍历过的重要点的数量
	unsigned short current_ans; //当前状态距离起点的距离
};


class RoadStatus
{
	public:
	bool isLegalSolution() //这个状态是否合法,是否存在路径到终点
	{
		return is_legal_solution;
	}
	bool setLegalSolution(bool flag)
	{
		is_legal_solution = flag;
	}
	
	private:
	bool is_legal_solution;
};

class Map
{

	public:
	vector<short> g[max_vertex_num]; //邻接表
	unsigned short total_vertex; //最大的顶点标号,所有点的标号为1~total_vertex, 前面1~total_importan_vertex为重要点,其中1为起点,total_importan_vertex为终点
	unsigned short total_importan_vertex;
	Vertex start_vertex;
	Vertex end_vertex;


	void setTotalVertex(short total_vertex) //修改最大顶点标号
	{
		this -> total_vertex = total_vertex;
	}

	inline void setTotalImportanVertex(unsigned short total_importan_vertex) //修改重要的点最大点标号
	{
		this -> total_importan_vertex = total_importan_vertex;
	}

	inline void insert(Vertex arg0, Vertex arg1, unsigned short distance, unsigned short edge_num)
		//arg0 -> arg1 距离是distance ,边的标号是edge_num
	{
		if (this -> distance[arg0][arg1] > distance)
		{
			g[arg0].push_back(arg1);
			this -> distance[arg0][arg1] = distance;
			this -> edge_num[arg0][arg1] = edge_num;		
		}else
		{
			//do nothing	
		}
	}

	inline void setStartVertex(Vertex start_vertex)
	{
		this -> start_vertex = start_vertex;
	}

	inline void setEndVertex(Vertex end_vertex)
	{
		this -> end_vertex = end_vertex;
	}

	inline bool isConnected(Vertex arg0, Vertex arg1) //判断arg0和arg1是否连通
	{
	//	return edge_num[arg0][arg1] != null_distance;
	}

	inline unsigned short getDistance(Vertex arg0, Vertex arg1)
	{
		return distance[arg0][arg1];
	}


	Map(Vertex start, Vertex end):
		start_vertex(start),end_vertex(end),
		null_edge_num(56789),null_distance(56789) //构造函数,清空所有的变量
	{
		total_vertex = 0; //所有的顶点的数量为0,
		for (int i = 0; i != max_vertex_num; i ++)
		{
			g[i].reserve(10);
			for (int j = 0; j != max_vertex_num; j ++)
			{
				distance[i][j] = null_distance;
				edge_num[i][j] = null_edge_num;
			}
		}
	}
	

	private:
	unsigned short distance[max_vertex_num][max_vertex_num]; //距离矩阵
	unsigned short edge_num[max_vertex_num][max_vertex_num]; //边标号矩阵,只记录最小的边标号
	const unsigned short null_edge_num;
	const unsigned short null_distance;
};



class CheckMap:public Map  //生成一个Check变量,来完成所有的check操作
{
	public:
		/*
	CheckMap():Map()//初始化的时候,先调用Map初始化一下
	{
		clear();	
	}*/
	//CheckMap(){}

	CheckMap(Vertex start, Vertex end):Map(start, end)
	{
		clear();
	}	

	void clear() //清理tarjan和BFS运算所需要的数组元素
	{
		memset(DFN, 0, sizeof(DFN));
		memset(LOW, 0, sizeof(LOW));
		memset(instack, 0, sizeof(instack));
		memset(my_stack, 0, sizeof(my_stack));
		memset(f, 0, sizeof(f));
		memset(belong, 0, sizeof(belong));
		memset(belong_vertex_evaluation, 2, sizeof(belong_vertex_evaluation)); //数组清最大值
		memset(f_vis, false, sizeof(f_vis));//点是否被访问过,每个点只会被访问一次。(讲道理是这样)
		Stop = din = count = 0;
		total_evaluation_valve = 0; //估价清0
	}

	
	void tarjan(Vertex current_vertex)
	{
		LOW[current_vertex] = DFN[current_vertex] = ++ din;
		my_stack[++ Stop] = current_vertex;
		instack[current_vertex] = true;
		for (int i = 0; i != g[current_vertex].size(); ++ i)
		{
			int will_vertex = g[current_vertex][i];
			if (map_status.isVisited(will_vertex))	continue;//这个点已经在地图中被移除了
			if (!DFN[will_vertex])
			{
				tarjan(will_vertex);
				LOW[current_vertex] = min(LOW[current_vertex], LOW[will_vertex]);
			}
			else if (instack[will_vertex])	LOW[current_vertex] = min(LOW[current_vertex], DFN[will_vertex]);
		}
		if (LOW[current_vertex] == DFN[current_vertex])
		{
			int tmp;
			++count;
			do
			{
				tmp = my_stack[Stop --];
				instack[tmp] = false;
				belong[tmp] = count;
				if (tmp <= total_importan_vertex)//属于重要点的范畴
				{
					f[count] |= 1 << (tmp - 1); //f[count]这个连通块多了一些元素
				}
			}while (tmp != current_vertex);
		}
	}

	StatusVertex evaluationVertexLiantong(Vertex current_vertex)
	{
		unsigned short lei = belong[current_vertex]; //只能走这个种类的点
		DFN[current_vertex] = true; //访问标记
		//DFN[i]
		for (int i = 0; i != g[current_vertex].size(); i ++ )
		{
			Vertex will_vertex = g[current_vertex][i];
			if (belong[will_vertex] != lei || current_status.isVisited(will_vertex))	continue;
			total_evaluation_valve += getDistance(current_vertex, will_vertex);
			evaluationVertexLiantong(will_vertex);
		}
	
	}

	//版本0.01的getF,看看能不能成功
	ImportantMap getF(Vertex current_vertex)
	{

		if (f_vis[current_vertex] == true)	return f[current_vertex];
		f_vis[current_vertex] = true;	//访问标记
		if (current_vertex == end_vertex)//如果已经到了end_vertex,那么显然不能走动了
		{
			return f[belong[end_vertex]];
		}
		for (int i = 0; i != g[current_vertex].size(); ++ i)
		{
			f[current_vertex] |= getF(g[current_vertex][i]);
		}
		return f[current_vertex];
	}

	bool findWay(Vertex current_vertex)//连通块,查看是否有解
	{
		if (current_vertex == end_vertex)
		{
			if (f[current_vertex] == f[belong[end_vertex]])	return true;
			//如果到达最重点,并且最重点能遍历的情况,和当前情况相同则为true
		}
		for (int i = 0; i != new_g[current_vertex].size(); ++ i)
		{
			Vertex will_vertex = new_g[current_vertex][i];
			if (f[will_vertex] == (f[current_vertex] ^ f_self[current_vertex]))
			{
				if (findWay(will_vertex))	return true;
			}
		}
		return false;
	}

	RoadStatus check(Status current_status)//当前路径状态
	{
		this -> current_status = current_status;
		RoadStatus check_ret;
		clear(); //先清空所有数组元素
		Vertex current_vertex = current_status.getCurrentVertex();//得到当前顶点

		for (int i = 0; i <= total_vertex; i ++)
			if (current_status.isVisited(i) &&  !DFN[i])	tarjan(i);//缩点
		memmove(f_self, f, sizeof(f_self)); //f_self全部是都是每个点自己的状态

		for (int i = 0; i <= total_vertex; i ++)//重新构图
		{
			g[i].clear();
			for (int j = 0; j != g[i].size(); ++ j)
			{
				if (map_status.isVisited(g[i][j]))	continue; 
				//新构的图,不包含非法路径,因为垃圾点直接就不在图里 
				new_g[belong[i]].push_back(belong[g[i][j]]);
				belong_vertex_evaluation[belong[g[i][j]]] =    //更新每个连通块入度最小值
					min(belong_vertex_evaluation[belong[g[i][j]]], getDistance(belong[i], belong[g[i][j]]));
				//belong[i] - > belong[g[i][j]]
			}
		}


		getF(belong[current_vertex]);//做一个DP,得到f数组



		check_ret.setLegalSolution(findWay(belong[current_vertex]));
		if (!check_ret.isLegalSolution())	return check_ret; //非法解,退出

		/*开始估价每个连通块入度的总权重*/
		for (int i = 1; i <= count; ++ i)	
		{
			if (belong_vertex_evaluation[i] == belong_vertex_evaluation[0])	continue; //连通块入度为0,就直接continue
			total_evaluation_valve += belong_vertex_evaluation[i];//每个状态的入度增加
		}

		/*开始对每个连通块的权重进行估价*/
		memset(f_vis, false, sizeof(f_vis));//这个访问标记数组又要用了,是否访问表示连通块是否访问过
		memset(DFN, false, sizeof(DFN)); // dfn[i]现在为某个点是否访问过了
		for (int i = 1; i <= total_vertex; ++ i)
		{
			if (current_status.isAccessible(i) || f_vis[belong[i]])	continue;
			f_vis[belong[i]] = true;
			evaluationVertexLiantong(i);
			// belong[i]   i所属连通块
		}
	}


	private:
	Status current_status; //当前路径状态
	unsigned short DFN[max_vertex_num];  //时间戳
	unsigned short LOW[max_vertex_num]; //最早追溯到的时间戳
	bool instack[max_vertex_num]; // 顶点是否属于栈
	unsigned short my_stack[max_vertex_num]; //手写的一个简单的栈
	unsigned short belong[max_vertex_num]; //原来每个点,所属的连通块
	unsigned short Stop, din, count;//栈顶编号0~?, 时间戳编号1~?, 缩点后,每个连通块的编号1~?
	bool f_vis[max_vertex_num];
	unsigned short belong_vertex_evaluation[max_vertex_num]; //每个连通块入度最小的值
	ImportantMap f_self[max_vertex_num]; //f_self[i]表示i这个连通块里自己所拥有的重要的点
	ImportantMap f[max_vertex_num];//f[i]表示i后继能到的点
	vector<Vertex> new_g[max_vertex_num]; //缩点后的新图,路径不包含非法点
	unsigned short total_evaluation_valve; // 计算状态的估价
	Status map_status; //传递过来处理的map状态
}check(1, 1);//起点和终点都是1,需要后来修改



int getnum()
{
	return (rand() % 10) + 1;
}

int main()
{
	freopen("input.txt", "r", stdin);
	int n, m;
	cin >> n >> m;
	//srand(100);
	for (int i = 0; i != m; ++ i)
	{
		int a, b;
		cin >> a >> b;
		check.insert(i, a, b, 1); //随机给定一个权重
	}
	int zhongyaodian;
	cin >> zhongyaodian;
	check.setEndVertex(zhongyaodian);
	return 0;
}


check_dag.cpp

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <vector>
#include <map>
#include <algorithm>
using namespace std;


int n, m;//n个点,m个边
vector<int>g[5000];
int zhongyao[5000], zhongyaodian;
int mp[5000]={0}; //是否是重要点

#define LL long long
int vis[5000] ={0}; //在dfs中是否被访问过
LL f[5000]={0}; //f[i]表示i这个节点,的根节点里,能到达的【重要节点】的数量(如果i是重要节点,那么f[i]的值也包含自己)。
int pre[5000];//记录路径

void insert(int a, int b)
{
	g[a].push_back(b);
}

void init()
{
	cin >> n >> m;
	for (int i = 1; i <= m; ++ i)
	{
		int a, b;
		cin >> a >> b ;
		insert(a, b);
	}
	cin >> zhongyaodian ;
	for (int i = 1; i <= zhongyaodian; ++ i)
	{
		int p;
		cin >> p;
		mp[p] = true;
	}
	memset(f, -1, sizeof(f));
	memset(pre, 0, sizeof(pre));
}

#define wei(k) (1LL<<(k-1))

LL dfs(int now) //得出上述的f数组
{
	if (f[now] != -1)	return f[now];
	if (now == n)	
	{
		return f[now] = wei(n);
	}
	if (mp[now])	f[now] = wei(now);
	else f[now] = 0;
	for (int i = 0; i != g[now].size(); ++ i)
	{
		int will = g[now][i];
		f[now] |= dfs(will);
	}
	return f[now];
}

int check(int now)
{
	if (now == n)
	{
		if (f[now] == (wei(n)))	return 1;
	}
	for (int i = 0; i != g[now].size(); ++ i)
	{
		int will = g[now][i];
		if (mp[now])//如果自己是重要点
		{
			if ( (f[will] | (wei(now))) == f[now])	
			{
				pre[will] = now;
				if (check(will))	return 1;
			}
		}else
		{
			if (f[will] == f[now])//总不能丢掉一些一定经过的节点吧?
			{
				pre[will]=now;
			//	if (will==8)	cout<<"!!!!!!!!!!!!!!!!!!"<<endl;
				if (check(will))	return 1;
			}
		}
	}
	return 0;
}

int main()
{
	init();
	dfs(1);
	cout << (check(1) ? "yes" : "no") << endl;
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
华为ICT大赛是华为公司主办的一项全球性技术竞赛活动,旨在发掘和培养全球优秀的ICT人才。其中,大数据初赛试题是这个竞赛的一个阶段。以下是我对华为ICT大赛大数据初赛试题的回答。 大数据初赛试题要求我们利用给定的大规模数据集进行数据处理和分析。题目主要涉及到以下几个方面: 首先,我们需要对数据集进行预处理,包括数据清洗和数据规范化。数据清洗过程中,我们会处理缺失、重复和异常值,确保数据质量。数据规范化则是将数据转换为统一的格式和单位,以便后续分析。 其次,我们需要利用大数据技术进行数据分析和挖掘。这包括使用机器学习算法对数据进行分类、聚类、关联分析等,以发现数据中的隐藏模式和有价值的信息。另外,我们也需要进行数据可视化,将分析结果以图表、图像等形式展示,使得结论更加直观和易懂。 最后,我们需要根据分析结果提出相应的解决方案和建议。例如,如果我们在分析过程中发现某个市场的用户需求较大,可以建议公司加大对该市场的投入力度;如果我们发现某个产品的特定功能很受欢迎,可以建议公司在下一版本中加强该功能的开发。 在答题过程中,我们需要充分运用自己所学的大数据技术和分析方法,同时能够结合实际场景,提出合理的分析方案和应对策略。通过这个竞赛,我们可以不断提升自己的技术能力,并与其他优秀的选手进行交流与竞争,为自己的职业发展打下坚实的基础。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值