poj1062(Dijkstra)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_26760433/article/details/84627594

这题用到了Dijkstra算法,难点在处理等级限制。我天真以为把前驱节点和当前访问节点比较一下就行了。too young too naive…这个需要枚举所有等级范围。
因为酋长是必须要访问的节点,所以要以酋长为中心枚举。比如说酋长等级是3,等级限制是4。符合条件的范围是-1—3、0—4、1—5、2—6、3—7(会有比酋长等级高的人)。所以需要搜索5次,把不符合条件的节点标记为不能访问。
比如果下面这组数据

4 5
800 3 2
2 1
3 2
20 1 1
4 1
30 5 1
4 2
100 4 1
5 0
5 7 0

根据数据建图
在这里插入图片描述

最优路径为:1->3->4->5 结果为 2+2+0+5=9。不能走1->2->4->5,因为顶点2的等级为1,顶点5的等级为7,等级差距大于4。
贴代码

//Memory 224k Time 47ms
#include<iostream>
#include<queue>
#include<vector>
using namespace std;
int M,N;
class road
{
public:
	int end;       //通向的节点
	int weight;    //路径的长度
};

class node
{
public:
	int value;       //价值
	int level;       //等级
}node[105];

class Graph
{
public:
	int v;           //顶点个数
	int mark[105];       //标记
	vector<road> *adj;  //邻接表
	Graph(int n);
	~Graph();
	void addEdge(int b,int e,int w);
};
Graph::Graph(int n)
{
	v=n;
	adj=new vector<road>[n];
}
Graph::~Graph()
{
	delete []adj;
}
void Graph::addEdge(int b,int e,int w)
{
	road r;
	r.end=e;
	r.weight=w;
	adj[b].push_back(r);
}

class Dist
{
public:
	int index;      //顶点号
	int length;     //长度
	friend  bool operator<(const Dist &a,const Dist &b)
	{
		return a.length>b.length;
	}
};

int Dijkstra(Graph & g,int s)
{
	Dist *D = new Dist[g.v];
	for(int i=1;i<g.v;i++)
	{
		D[i].index = i;
		D[i].length=1<<30;
	}
	D[s].length=0;
	priority_queue<Dist> aqueue;
	aqueue.push(D[s]);

	for(int i=1;i<g.v;i++)
	{
		Dist d;
		bool FOUND=false;
		while(!aqueue.empty())
		{
			d=aqueue.top();
			aqueue.pop();
			if(g.mark[d.index]==0)
			{
				FOUND=true;
				break;
			}
		}
		if(!FOUND)
			break;
		int now_node = d.index;
		g.mark[now_node]=1;
		vector<road>::iterator ii = g.adj[now_node].begin();
		for(;ii!=g.adj[now_node].end();ii++)
		{
			if(  g.mark[ii->end]==0 && D[ii->end].length > D[now_node].length + ii->weight)
			{
				D[ii->end].length = D[now_node].length + ii->weight;
				aqueue.push(D[ii->end]);
			}
		}
	}
	int *ans=new int[g.v];
	for(int i=1;i<g.v;i++)
	{
		ans[i]=D[i].length+node[i].value;
	}
	int min=1<<30;
	for(int i=1;i<g.v;i++)
	{
		if(ans[i]<min)
		{
			min=ans[i];
		}
	}
	return min;
}
int main()
{
	int P,L,X;
	int T,V;
	cin>>M>>N;
	Graph g(N+1);
	for(int i=1;i<=N;i++)
	{
		cin>>P>>L>>X;
		node[i].value=P;
		node[i].level=L;
		for(int j=1;j<=X;j++)
		{
			cin>>T>>V;
			g.addEdge(i,T,V);
		}
	}
	int ans=1<<30;
	for(int i=node[1].level - M; i<=node[1].level; i++)  //等级筛选
	{
		memset(g.mark,0,sizeof(g.mark));
		for(int j=1;j<g.v;j++)
		{
			if(node[j].level<i || node[j].level>i+M)      //不符合条件
			{
				g.mark[j]=1;                          //标记
			}
		}
		ans=min(Dijkstra(g,1),ans);              //搜索

	}
	cout<<ans<<endl;
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_26760433/article/details/84627594
今日推荐