您的位置:首页 > 大数据 > 人工智能

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

2016-08-22 10:04 357 查看

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 城市的花费前提:

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

如果从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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: