POJ - 3411 Paid Roads (状态压缩DP)

来源:互联网 发布:centos下载安装jdk 编辑:程序博客网 时间:2024/06/05 03:35

Paid Roads

Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 6750 Accepted: 2505


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


题意

给定N 个城市和m 条边,让你求出从1 N 城市最少花费为多少。
给出的数据要求:
a b c C[0] C[1]
a b 城市的花费前提:

  1. 如果在从a b 城市之前经历过c 城市的话,花费为C[0] ,反之为C[1] .

  2. 如果从1 城市无法到达N 城市,就输出impossible.

解题思路:状态压缩DP

我们可以非常快速的列出状态转移方程:

dp[i][j]:=  状态为i ,以j 城市为结尾的最小花费(其中i 保存的是已经经历过的点)

dp[i | 1 << a][b] = min(dp[i | 1 << a][b], dp[i][a] + C[~ i >> c & 1]);

C[~ i >> c &1]:如果包含了c ,用C[0] ,否则用C[1] .

然后我们需要对边的数据进行排序,因为我们是固定了起点和终点的,所以接近起点的要先进行处理。尤其是和城市1 有联系的边必须先处理


/*头文件模板*/#include <map>#include <set>#include <cmath>#include <ctime>#include <queue>#include <stack>#include <vector>#include <cctype>#include <cstdio>#include <string>#include <cstring>#include <sstream>#include <cstdlib>#include <iomanip>#include <typeinfo>#include <iostream>#include <algorithm>#include <functional>using namespace std;#define pb push_back#define mp make_pair#define mem(a, x) memset(a, x, sizeof(a))#define copy(a, b) memcpy(a, b, sizeof(a))#define lson rt << 1, l, mid#define rson rt << 1|1, mid + 1, r#define FIN freopen("input.txt", "r", stdin)#define FOUT freopen("output.txt", "w", stdout)typedef long long LL;typedef pair<int, int > PII;typedef pair<int, string> PIS;typedef pair<LL, LL>PLL;typedef unsigned long long uLL;template<typename T>void print (T* p, T* q, string Gap = " ", bool flag = false) {    int d = p < q ? 1 : -1;    while (p != q) {        if (flag) cout << Gap[0] << *p << Gap[1];        else cout << *p;        p += d;        if (p != q && !flag) cout << Gap;    }    cout << endl;}template<typename T>void print (const T &a, string bes = "") {    int len = bes.length();    if (len >= 2) cout << bes[0] << a << bes[1] << endl;    else cout << a << endl;}template<typename T>void debug (T* p, T* q, string Gap = " ", bool flag = false) {#ifndef ONLINE_JUDGE    int d = p < q ? 1 : -1;    cout << "Debug out : ";    while (p != q) {        if (flag) cout << Gap[0] << *p << Gap[1];        else cout << *p;        p += d;        if (p != q && !flag) cout << Gap;    }    cout << endl;#endif}template<typename T>void debug (const T &a, string bes = "") {#ifndef ONLINE_JUDGE    int len = bes.length();    cout << "Debug out : ";    if (len >= 2) cout << bes[0] << a << bes[1] << endl;    else cout << a << endl;#endif}void IO_Init() {    ios::sync_with_stdio (false);}LL LLabs (const LL a) {    return a >= 0 ? a : -a;}const double PI = 3.1415926535898;const double eps = 1e-10;const int MAXM = 1e5 + 5;const int MAXN = 10 + 5;const int INF = 0x3f3f3f3f;/*头文件模板*/int N, m, dp[1 << MAXN][MAXN];int x, y, c, c1, c2;struct o {    int x, y, c;    int C[2];    bool operator < (const o &p) const {        if(x == p.x) return y < p.y;        return x < p.x;    }} O[MAXN];int main() {#ifndef ONLINE_JUDGE    FIN;    FOUT;#endif    IO_Init();    while(~scanf("%d%d", &N, &m)) {        mem(dp, 0x3f);        for(int i = 0; i < m; i ++) {            scanf("%d%d%d%d%d", &O[i].x, &O[i].y, &O[i].c, &O[i].C[0], &O[i].C[1]);            O[i].x --;            O[i].y --;            O[i].c --;        }        sort(O, O + m);        dp[0][0] = 0;        for(int i = 0; i < (1 << N) - 1; i ++) {            for(int j = 0; j < m; j ++) {                int a = O[j].x, b = O[j].y, c = O[j].c;                dp[i | 1 << a][b] = min(dp[i | 1 << a][b], dp[i][a] + O[j].C[~ i >> c & 1]);            }        }        int ans = INF;        for(int i = 0; i < (1 << N) - 1; i ++) {            ans = min(ans, dp[i][N - 1]);        }        if(ans == 0x3f3f3f3f) {            printf("impossible\n");        } else {            printf("%d\n", ans);        }    }    return 0;}
1 0
原创粉丝点击