初步 poj3159Candies

终于放假了,考试爆炸,算了,还不如学学算法,Dijkstra`s算法。。。

先给题目链接好吧,poj3159Candies:http://poj.org/problem?id=3159  

题目意思抄一下:

有N个孩子(N<=3000)分糖果。有M个关系(M<=150000)。每个关系形如:

A B C

表示第B个学生比第A个学生多分到的糖果数目,不能超过C

求第N个学生最多比第1个学生能多分几个糖果 。

这题目交上去还是蛮坑的,开始一直超时,以后有空再问问坤哥。

贴代码吧。


#include<iostream>
#include<queue>
#include<vector>
#include <cstdio>
using namespace std;
int N , M;
struct CNode{
	int k , w;//到k点,中间权值为w ; 
	bool operator <(const CNode &b)const{
	return w > b.w; //优先队列重载大于号,保证小的在上; 
	}
	CNode(){};//构造函数,方便直接带入 
	CNode(int k,int w):k(k),w(w){}; 
}p , q;
priority_queue<CNode> pq;//优先队列 
const int INF = 2e9;//给dis表赋无穷大 
vector <int> dis;//dis表,保证单源到其他点的最优权值,这题用不到,但是也可以用 
vector <bool> bUsed;// 记录这个点是否已经是最优 
vector<vector<CNode> >v;//邻接表 
int main() {
	scanf("%d%d", & N, & M );//这里最坑。。若果这里用cin>>N>>M;就会超时; 
	v.clear() , v.resize(N + 1);//3个初始化 
	dis.clear() , dis.resize(N + 1 , INF);
	bUsed.clear() , bUsed.resize(N+1 , false);
	for(int i = 1;i <= M;++i){//造图 
		int re, rs, ci;//A,B,c
		scanf("%d%d%d", & re, & rs, & ci);//用cin需要加关闭
		v[re].push_back( CNode(rs,ci) );
	}
	//开始D算法 
	pq.push( CNode(1,0) );//初始点 1 压入队列,1-1权值为0; 
	while(!pq.empty()){//若队列为空,则所有和 1 有边的点都排除 
		p = pq.top() ; pq.pop();//取最上值; 
		if(bUsed[p.k]) continue;//若果这个点已经求出解,就看下个点; 
		bUsed[p.k] = true;//第一次见点,保证一个点一次 
		if(p.k == N) break;//本题只要1-N,所以不用dis,只要到N就行,若果想用表,dis[p.k]=p.w;记录数据 
		for(int i = 0,j = v[p.k].size(); i < j ; ++i){ 
			q.k = v[p.k][i].k; // p.k所能到的点 
			if(bUsed[q.k]) continue;//q.k已经求出,跳过 
			q.w = p.w+v[p.k][i].w;//记录两点权值和; 
			pq.push(q);//优先队列保证最小在上,即使p到p.k有值,也只会保留最小值,记录bUsed数组,下次见到直接跳; 
		} 
	}
	cout << p.w;//输出1-N; 
	return 0;
}

programming is the most fun you can have with your clothes on.

猜你喜欢

转载自blog.csdn.net/A_Pathfinder/article/details/81102129