最短路径附带限制问题

这一节要讨论的是带有额外条件的DP问题。

以下的这个问题是个很好的例子。

无向图G有N个结点,它的边上带有正的权重值。

你从结点1开始走,并且一开始的时候你身上带有M元钱。如果你经过结点i, 那么你就要花掉S[i]元(可以把这想象为收过路费)。如果你没有足够的钱, 就不能从那个结点经过。在这样的限制条件下,找到从结点1到结点N的最短路径。 或者输出该路径不存在。如果存在多条最短路径,那么输出花钱数量最少的那条。 限制:1

#include
#include
#include
using namespace std;

struct my{
       int next,v,w,cost;
};


const int maxn=1000;
const int nil=0x7f7f7f7f;

int tot;
my bian[maxn];
int n,m;
int adj[maxn];
int dp[maxn][maxn],zhi;
bool vis[maxn][maxn];

void myinsert(int u,int v,int w,int cost){
     bian[++tot].v=v;
     bian[tot].next=adj[u];
     adj[u]=tot;
     bian[tot].w=w;
     bian[tot].cost=cost;
}

void dij(){
    for (int i=0;i<=n;i++)
        for (int j=0;j<=zhi;j++) dp[i][j]=nil;
    dp[1][zhi]=0;
    while(true){
        int l,k;
        int minn=nil;
        for (int i=1;i<=n;i++)
            for (int j=1;j<=zhi;j++)
            if(!vis[i][j]&&dp[i][j]j;
        if(minn==nil) break;
        vis[l][k]=true;
        for (int i=adj[l];i;i=bian[i].next){
            int v=bian[i].v;
            if(k-bian[i].cost>=0&&dp[v][k-bian[i].cost]>dp[l][k]+bian[i].w){
                dp[v][k-bian[i].cost]=dp[l][k]+bian[i].w;
            }
        }
    }
}
int main(){
    int u,v,w,cost;
    scanf("%d%d%d",&n,&m,&zhi);
    for (int i=1;i<=m;i++){
        scanf("%d%d%d%d",&u,&v,&w,&cost);
        myinsert(u,v,w,cost);
        myinsert(v,u,w,cost);
    }
    dij();
    int ans=nil;
    for (int j=1;j<=zhi;j++)
        if(dp[n][j]<=ans) ans=dp[n][j];
    printf("%d\n",ans);
return 0;
}

 

转载于:https://www.cnblogs.com/lmjer/p/9489351.html

你可能感兴趣的:(最短路径附带限制问题)