poj 3411 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 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
Source
#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; }