昂贵的聘礼-dijkstra
update@2011-10-24
#define MAX 110
int M;//最大的差值
struct men{
int rank,price;
}me[110];
struct node{
int u,v,w,next;//顶点结构体
}edge[110*110];
int head[MAX],countt=0;//每次都要初始化
void add(int u,int v,int w){//加边
edge[countt].u = u;
edge[countt].v = v;
edge[countt].w = w;
edge[countt].next = head[u];head[u] = countt++;
}
struct node2{
int ver,dist,rank_min,rank_max; //从ver出发可以以dist+自己的价格得到1物品
node2(int v,int d,int rm,int rn){ver = v;dist = d;rank_max = rm;rank_min = rn;}
};
bool operator > (const node2 &a,const node2 &b){
//重载优先队列的 > 运算符
if(a.dist > b.dist)return true;
return false;
}
bool operator < (const node2 &a,const node2 &b){
//重载优先队列的 < 运算符
if(a.dist < b.dist)return true;
return false;
}
long long dijkstra(int source,int vertex_num,int end=-1,int flag=0){
long long dist[MAX];
//优先队列(小根,top为最小值)
priority_queue<node2,vector<node2>,greater<node2> > my;
for(int i = 1;i <= vertex_num;i++){
dist[i] = 1000000000000000000;
}dist[source] = 0;
my.push(node2(source,0,me[source].rank,me[source].rank));//放入源点
int pre_of[MAX]; memset(pre_of,-1,sizeof(pre_of));
while(!my.empty()){
node2 u = my.top();my.pop();
if(flag && u.ver == end){return dist[u.ver];}
for(int i = head[u.ver];i != -1;i = edge[i].next){
int v = edge[i].v,w = edge[i].w;
//不能超过M,不仅从低到高不能,从高到低也不能 第一个卡的地方 = =,
if(u.rank_max-me[v].rank > M || me[v].rank - u.rank_min > M)continue;
if(dist[v] > u.dist+w){
//不能用dist[u.ver] + w去比较
//如果这样比较,dist[u.ver]保存的就是最近的距离
//但我们要求的是在满足条件的前提下的最近距离
//而且dist[i]只有一个,而u.dist可以有多个,我们都把它们扔在队列里
//第二个卡的地方 = =.就这样一半天没有了
dist[v] = u.dist+w;
pre_of[v] = u.ver;//保存路径
my.push(node2(v,dist[v],mymax(u.rank_max,me[v].rank),\
mymin(u.rank_min,me[v].rank)));
}
}
}
long long minn = me[source].price;
for(int i = 1;i<= vertex_num;i++){
if(dist[i]+me[i].price < minn){
minn = dist[i]+me[i].price;
}
}return minn;
}
昂贵的聘礼贴个题吧,最短路,这题稍微麻烦点,很多坑(见代码注释)。最短路我一直只会floyd,这几天看课件遇到dijkstra,发现和SPFA差不多 = =.