(poj 1724 ROADS)<二维最短路+DP>

来源:互联网 发布:门罗主义 知乎 编辑:程序博客网 时间:2024/06/15 15:50

传送门

题意:每条边有长度和代价,在代价不超过k的前提下走最短路

dis[i][j]表示走到点i花费j的代价的最短路
所以dis[i][j]=min{dis[u][j-e[i].cost]+e[i].d}
很像背包

Code

// by spli#include<cstring>#include<iostream>#include<queue>#include<algorithm>#include<cstdio>using namespace std;const int N=210;const int M=10010;const int K=10010;const int inf=1061109567;//用memset赋值数组得到的值int k,n,m;struct node{    int to,nxt,d,v;}e[M];int head[N],cnt;int dis[N][K];bool vis[N];queue<int>q;void add(int f,int t,int v,int c){    cnt++;    e[cnt]=(node){t,head[f],v,c};    head[f]=cnt;}void spfa(){    memset(dis,0x3f3f3f3f,sizeof(dis));    q.push(1);dis[1][0]=0;vis[1]=1;    while(!q.empty()){        int u=q.front();        q.pop();        vis[u]=0;        for(int i=head[u];i!=-1;i=e[i].nxt){            int v=e[i].to;            for(int j=e[i].v;j<=k;++j)                if(dis[u][j-e[i].v]+e[i].d<dis[v][j]){                    dis[v][j]=dis[u][j-e[i].v]+e[i].d;                    if(!vis[v]){                        q.push(v);                        vis[v]=1;                    }                }        }    }}int main(){    memset(head,-1,sizeof(head));    scanf("%d%d%d",&k,&n,&m);    int s,t,d,c;    for(int i=1;i<=m;++i){        scanf("%d%d%d%d",&s,&t,&d,&c);        add(s,t,d,c);    }    spfa();    int ans=inf;    for(int i=0;i<=k;++i)        ans=min(ans,dis[n][i]);    if(ans>=inf) cout<<-1;    else cout<<ans;    return 0;}
原创粉丝点击