Paid Roads POJ

A network of m roads connects N cities (numbered from 1 to N). There may be more than one road connecting one city with another. Some of the roads are paid. There are two ways to pay for travel on a paid road i from city ai to city bi:

  • in advance, in a city ci (which may or may not be the same as ai);
  • after the travel, in the city bi.

The payment is Pi in the first case and Ri in the second case.

Write a program to find a minimal-cost route from the city 1 to the city N.

Input

The first line of the input contains the values of N and m. Each of the following m lines describes one road by specifying the values of ai, bi, ci, Pi, Ri (1 ≤ i m). Adjacent values on the same line are separated by one or more spaces. All values are integers, 1 ≤ m, N ≤ 10, 0 ≤ Pi , Ri ≤ 100, PiRi (1 ≤ i m).

Output

The first and only line of the file must contain the minimal possible cost of a trip from the city 1 to the city N. If the trip is not possible for any reason, the line must contain the word ‘impossible’.

Sample Input
4 5
1 2 1 10 10
2 3 1 30 50
3 4 3 80 80
2 1 2 10 10
1 3 2 10 50
Sample Output
110

题解:
  一开始看错题了,wa了好多次,真是浪费时间。
  这个题目,状态十分显然,dp[i][s]表示处于节点i,当前经过点的集合为s的最小花费,那么转移就是枚举边转移就可以了,注意,如果可以用情况1就必须用情况1.
  初始化的时候都为inf,让他们不能更新其他状态,然后这个有后效性,必须spfa。
代码:
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <iostream>
#include <queue>
#define MANXN 15
#define MAXNM 2100
#define ll long long
using namespace std;
int dp[MANXN][1<<MANXN],have[MANXN][1<<MANXN];
int n,m,num=0,inf;
struct edge{
    int first;
    int next;
    int to,c,p,r;
}a[MAXNM*2];
struct heapnode{
    int id;ll S;
};
queue<heapnode> q;

void addedge(int from,int to,int c,int p,int r){
    a[++num].to=to,a[num].p=p,a[num].r=r,a[num].c=c;
    a[num].next=a[from].first;
    a[from].first=num;
}

void spfa(){
    memset(dp,127/3,sizeof(dp));inf=dp[0][0];
    memset(have,0,sizeof(have));
    dp[1][1]=0;q.push((heapnode){1,1});have[1][1]=1;
    while(!q.empty()){
        int now=q.front().id;
        ll s=q.front().S;
        have[now][s]=0;
        q.pop();
        for(int i=a[now].first;i;i=a[i].next){
            int to=a[i].to;
            if(s&(1<<(a[i].c-1))){
                if(dp[to][s|(1<<(to-1))]>dp[now][s]+a[i].p){
                    dp[to][s|(1<<(to-1))]=dp[now][s]+a[i].p;
                    if(!have[to][s|(1<<(to-1))]) {
                        have[to][s|(1<<(to-1))]=1;
                        q.push((heapnode){to,s|(1<<(to-1))});
                    }
                }
            }
            else{
                if(dp[to][s|(1<<(to-1))]>dp[now][s]+a[i].r){
                    dp[to][s|(1<<(to-1))]=dp[now][s]+a[i].r;
                    if(!have[to][s|(1<<(to-1))]){
                        have[to][s|(1<<(to-1))]=1;
                        q.push((heapnode){to,s|(1<<(to-1))});
                    }
                }
            }
        }
    }
}

int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++){
        int x,y,c,p,r;scanf("%d%d%d%d%d",&x,&y,&c,&p,&r);
        addedge(x,y,c,p,r);
    }
    spfa();
    int ans=inf;
    for(int i=0;i<=(1<<n)-1;i++){
        ans=min(ans,dp[n][i]);
    }
    if(ans==inf)cout<<"impossible";
        else cout<<ans;
    return 0;
}
原文地址:https://www.cnblogs.com/renjianshige/p/7507342.html