poj 3411 Paid Roads

Paid Roads
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 7996   Accepted: 2982

Description

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 aibiciPiRi (1 ≤ ≤ 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, Pi ≤ Ri (1 ≤ ≤ 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

Source

Northeastern Europe 2002, Western Subregion
题意:求最短路,不过每条边的权值有变化:如果已经经过了某一个特定顶点c的情况下再通过当前边,边权值为P,否则权值为R
思路:最短路+状态压缩
当经过某一条边要确定这条边的权值的时候,要事先记录当前已经经过的顶点集才行,显然可以用状态压缩解决。
AC代码:
#define _CRT_SECURE_NO_DEPRECATE
#include <iostream>
#include<vector>
#include<algorithm>
#include<cstring>
#include<bitset>
#include<set>
#include<map>
#include<cmath>
#include<queue>
using namespace std;
#define N_MAX 12
#define MOD 100000000
#define INF 0x3f3f3f3f
typedef long long ll;
struct edge {
    int to, c, cost1, cost2;//去过c就付cost1
    edge(int to = 0, int c = 0, int cost1 = 0, int cost2 = 0) :to(to), c(c), cost1(cost1), cost2(cost2) {}
};
struct P {
    int tot, cur, s;
    P() {}
    P(int tot, int cur, int s) :tot(tot), cur(cur), s(s) {}
    bool operator < (const P&b)const {
        return tot > b.tot;
    }
};
int n, m;
vector<edge>G[N_MAX];
int dp[1 << N_MAX][N_MAX];//当前经过的集合是S,当前在节点j

void dijkstra(int s) {
    priority_queue<P>que;
    que.push(P(0, 0, 1));
    memset(dp, INF, sizeof(dp));
    dp[1 << 0][0] = 0;
    while (!que.empty()) {
        P p = que.top(); que.pop();
        int v = p.cur;
        if (dp[p.s][v] < p.tot)continue;
        for (int i = 0; i < G[v].size();i++) {
            edge e = G[v][i];
            if (p.s >> e.c & 1) {//已经过节点c
                int min_cost = min(e.cost1, e.cost2);
                if (dp[p.s | 1 << e.to][e.to] > dp[p.s][v] + min_cost) {
                    dp[p.s | 1 << e.to][e.to] = dp[p.s][v] + min_cost;
                    que.push(P(dp[p.s | 1 << e.to][e.to], e.to, p.s | 1 << e.to));
                }
            }
            else if(dp[p.s | 1 << e.to][e.to] > dp[p.s][v] + e.cost2){
                dp[p.s | 1 << e.to][e.to] = dp[p.s][v] + e.cost2;
                que.push(P(dp[p.s | 1 << e.to][e.to], e.to, p.s | 1 << e.to));
            }
        }
    }
}

int main() {
      scanf("%d%d", &n, &m);
        for (int i = 0; i < m; i++) {
            int from, to, c, cost1, cost2;
            scanf("%d%d%d%d%d", &from, &to, &c, &cost1, &cost2);
            from--, to--, c--;
            G[from].push_back(edge(to, c, cost1, cost2));
        }
        dijkstra(0);
        int mincost = INF,allstates=1<<n;
        for (int i = 0; i < allstates;i++) {
            mincost = min(mincost, dp[i][n - 1]);
        }
        if (mincost == INF)
            puts("impossible");
        else printf("%d\n",mincost);
    
    return 0;
}

 

 

posted on 2018-04-09 18:57  ZefengYao  阅读(130)  评论(0编辑  收藏  举报

导航