昂贵的聘礼-dijkstra

update@2011-10-24
C++语言: 高亮代码由发芽网提供

#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差不多 = =.