POJ 1062 Dijkstra

POJ少有的中文题 (很久之前就想写来着,但是原来不会啊…..)
思路:
首先我们可以新建一个点,从这个点向每个物品连一条权值为这个物品价值的边 (这样就把点权转化成了边权对吧……)
我们已经知道了一个物品的替代品是啥,那么就可以从每个替代品向这个物品连一条边权为替代品价值的边。
是不是很有道理。。。

随后枚举区间 (区间里得包括酋长的地位)

每次枚举从新建的点向一号点跑一遍Dijkstra就OK了。

//By SiriusRen
#include <queue>
#include <cstdio>
#include <cstring>
#define N 100050
using namespace std;
int n,m,xx,yy,zz,ww,vis[105],d[105],answer=0x3fffffff;
int tot=0,first[105],next[N],v[N],w[N],p[105];
void add(int from,int to,int weight){
    v[tot]=to;w[tot]=weight;
    next[tot]=first[from];first[from]=tot++;
}
struct Node{int position,weight;}top,jy;
bool operator < (Node a,Node b){
    return a.weight>b.weight;
}
priority_queue<Node>pq;
int main(){
    scanf("%d%d",&m,&n);
    memset(first,-1,sizeof(first));
    for(int i=1;i<=n;i++){
        scanf("%d%d%d",&xx,&p[i],&zz);
        add(0,i,xx);
        while(zz--){
            scanf("%d%d",&xx,&ww);
            add(xx,i,ww);
        }
    }
    for(int T=-m;T<=0;T++){
        memset(d,0x3f,sizeof(d));
        memset(vis,0,sizeof(vis));
        xx=p[1]+T;yy=p[1]+T+m;
        d[0]=jy.position=0,jy.weight=0;pq.push(jy);
        while(!pq.empty()){
            top=pq.top();pq.pop();
            if(vis[top.position])continue;
            vis[top.position]=1;
            for(int i=first[top.position];~i;i=next[i])
            {
                if(d[v[i]]>d[top.position]+w[i]&&!vis[v[i]]&&p[v[i]]>=xx&&p[v[i]]<=yy)
                {
                    d[v[i]]=d[top.position]+w[i];
                    jy.position=v[i];
                    jy.weight=top.weight+w[i];
                    pq.push(jy);
                }
            }
        }
        answer=min(answer,d[1]);
    }
    printf("%d
",answer);
}

这里写图片描述

原文地址:https://www.cnblogs.com/SiriusRen/p/6532324.html