poj 3159 Candies

/*

题意: 在满足b1-a1<=c1,b2-a1<=c2...的情况下,flymouse( N )希望自己分得的糖果数尽量多于snoopy( 1 )
b-a<=c 不等式正好可以构成最短路的三角不等式:dv <= du + w(u,v)
比如顶点A,B,C有如下关系:db-da<=2,dc-da<=5,dc-db<=2,构成一三角形ABC,
AB(A指向B),AC(A指向C),BC(B指向C),由dc-db<=2,db-da<=2,知dc<=db+2,db<=da+2,所以dc<=da+4
而原条件 dc-da<=5,即dc<=da+5, 二者相比较,结果是dc<=da+4 所以实际上是求最短路
要使得|dn-d1|的值最大,我们只关心二者的相对量,而不关心其绝对量,所以完全可以假定d1=0
以V1作为起点,distD[1]=0;求最短路径,distD[N]就是所求的

*/


#include<cstdio> //邻接链表+优先队列实现Dijkstra算法
#include<cstring>

#include<queue>
using namespace std;

const int INF = INT_MAX;
const int MAXN = 30000;
const int MAXM = 150000 ;

int n, m; //结点数和边数,结点下标从0开始
int first[MAXN], distD[MAXN],done[MAXN];

int u[MAXM], v[MAXM], w[MAXM], Next[MAXM];

typedef pair<int,int> pii;
void init()
{
fill(first,first+n,-1);
for(int e = 0; e < m; e++)
{
scanf("%d%d%d", &u[e], &v[e], &w[e]); //有向边u->v
u[e]--; v[e]--;

Next[e] = first[u[e]];
first[u[e]] = e; //first[u]保存结点u的第一条边的编号,next[e]表示编号为e的边的“下一条边”的编号
}

}
void Dijkstra(int st)
{
priority_queue<pii, vector<pii>, greater<pii> > q;
fill(distD,distD+n,INF);
distD[st]=0;
fill(done,done+n,0);
q.push(make_pair(distD[st], st));
int cnt=0;
while(!q.empty())
{
pii u = q.top();
q.pop();
int x = u.second;
if(done[x])
continue;
done[x] = 1;
if(x==n-1)
{
printf("%d\n",distD[n-1]); //起点是1,终点是N
break;

}
for(int e = first[x]; e != -1; e = Next[e])
if(!done[v[e]]&&distD[v[e]] > distD[x]+w[e])
{
distD[v[e]] = distD[x] + w[e];
q.push(make_pair(distD[v[e]], v[e]));
}
}
}
int main()
{
while(scanf("%d%d", &n, &m)!=EOF) //n个结点,m条边
{

init();
Dijkstra(0);
}
return 0;
}

posted on 2011-07-22 20:40  sysu_mjc  阅读(148)  评论(0编辑  收藏  举报

导航