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
解题思路:一开始误以为每条边只能走一次,然后果断用了状压DP来搞这题,结果交的时候WA到死,无奈去POJ看discuss,看有个人的一组数据中表示同一条边可能经过多次,那我的状压DP很显然是错误的。后来网上有人总结每个节点的次数最多能能访问的次数,因此我们完全可以采用dfs来进行搜索即可,给定每个节点限制访问次数为3次,然后在所有可能的路径中选取最小值即可,只到每个节点最多能够访问的次数为3次,那这道题就水到家了,但自己就是想不到,努力刷体提高自己的水平吧。
参考博客:http://blog.youkuaiyun.com/lyy289065406/article/details/6689310
#include <ctime> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <iostream> #include <string> #include <vector> #include <deque> #include <list> #include <stack> #include <queue> #include <map> #include <set> #include <numeric> #include <utility> #include <algorithm> #include <functional> using namespace std; const int inf = 0x3f3f3f3f; const int maxn = 110; struct Edge { int a, b, c, p, r, next; Edge() { } Edge(int t_a, int t_b, int t_c, int t_p, int t_r, int t_next) : a(t_a), b(t_b), c(t_c), p(t_p), r(t_r), next(t_next) { } }edges[maxn]; int head[20]; int edge_sum; void init_graph() { edge_sum = 0; memset(head, -1, sizeof(head)); } void add_edge(int a, int b, int c, int p, int r) { edges[edge_sum].a = a; edges[edge_sum].b = b; edges[edge_sum].c = c; edges[edge_sum].p = p; edges[edge_sum].r = r; edges[edge_sum].next = head[a]; head[a] = edge_sum++; } int vis[20]; int ans; int n, m; void dfs(int u, int cost) { if(ans <= cost) return ; if(u == n) { ans = min(ans, cost); return ; } for(int i = head[u]; i != -1; i = edges[i].next) { int v = edges[i].b; if(vis[v] < 3) { vis[v]++; int t = edges[i].r; if(vis[edges[i].c]) { t = min(t, edges[i].p); } dfs(v, cost + t); vis[v]--; } } return ; } int main() { //freopen("aa.in", "r", stdin); int a, b, c, p, r; while(scanf("%d %d", &n, &m) != EOF) { init_graph(); for(int i = 0; i < m; ++i) { scanf("%d %d %d %d %d", &a, &b, &c, &p, &r); add_edge(a, b, c, p, r); } ans = inf; dfs(1, 0); if(ans < inf) { printf("%d\n", ans); } else { printf("impossible\n"); } } return 0; } /* struct Edge { int a, b, c, p, r; Edge() { } Edge(int t_a, int t_b, int t_c, int t_p, int t_r) : a(t_a), b(t_b), c(t_c), p(t_p), r(t_r) { } }E[20]; int dp[(1<<10)+10][15]; int vh[(1<<10)+10]; int n, m; int main() { freopen("aa.in", "r", stdin); while(scanf("%d %d", &n, &m) != EOF) { for(int i = 0; i < m; ++i) { scanf("%d %d %d %d %d", &E[i].a, &E[i].b, &E[i].c, &E[i].p, &E[i].r); E[i].a--; E[i].b--; E[i].c--; } memset(vh, 0, sizeof(vh)); for(int i = 0; i < (1<<m); ++i) { for(int j = 0; j < m; ++j) { if(i&(1<<j)) { vh[i] |= (1<<E[j].a); vh[i] |= (1<<E[j].b); } } } memset(dp, inf, sizeof(dp)); dp[0][0] = 0; for(int i = 1; i < (1<<m); ++i) { for(int j = 0; j < n; ++j) { if(!(vh[i]&(1<<j))) continue; for(int k = 0; k < m; ++k) { if(E[k].b == j && (i&(1<<k)) && dp[i^(1<<k)][E[k].a] < inf) { dp[i][j] = min(dp[i][j], dp[i^(1<<k)][E[k].a] + E[k].r); if(vh[i^(1<<k)]&(1<<E[k].c)) { dp[i][j] = min(dp[i][j], dp[i^(1<<k)][E[k].a] + E[k].p); } } } } } int ans = inf; for(int i = 0; i <(1<<m); ++i) { ans = min(ans, dp[i][n-1]); } if(ans < inf) { printf("%d\n", ans); } else { printf("impossible\n"); } } return 0; } */