Description
A network of m roads connects N cities (numbered from 1 toN). 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 roadi from city ai to city bi:
- in advance, in a city ci (which may or may not be the same asai);
- 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 ofai, 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 cityN. 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 题意:给定一张图,每条边的费用是p(如果经过节点c)或者r(没有经过c),求1->n的最小花费。 最开始我的想法是dfs,我认为每条边最多只走一次,如果大于一次,花费会增加,走两次可以做的事情, 一次也可以做到,结果WA,然后发现如果存在环上的点在后面需要经过的时候就会发现一条边会走多次。 网上看到的一个样例6 5
1 2 1 10 10
2 3 4 10 100
2 4 2 15 15
4 1 1 12 12
3 6 6 10 10
结果应该是67,但是如果按照每条边只能走一次的结果是120。
然后最多10条边,一条边最多走4次。
看到网上的题解是通过标记点,因为一个点最多经过4次(但网上别人题解说的3次,但他程序是4次)。
标记边的代码:
Accepted | 672 KB | 204 ms | G++ |
#include <stdio.h>
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <string>
#include <map>
#include <cmath>
#include <queue>
#include <set>
using namespace std;
//#define WIN
#ifdef WIN
typedef __int64 LL;
#define iform "%I64d"
#define oform "%I64d\n"
#define oform1 "%I64d"
#else
typedef long long LL;
#define iform "%lld"
#define oform "%lld\n"
#define oform1 "%lld"
#endif
#define S64I(a) scanf(iform, &(a))
#define P64I(a) printf(oform, (a))
#define S64I1(a) scanf(iform1, &(a))
#define P64I1(a) printf(oform1, (a))
#define FOR(i, s, t) for(int (i)=(s); (i)<(t); (i)++)
const int INF = 0x3f3f3f3f;
const double eps = 10e-9;
const double PI = (4.0*atan(1.0));
const int maxn = 10 + 2;
struct Road {
int a, b, c, p, r;
};
Road roads[maxn];
int vis[maxn];
int visr[maxn];
int n, m;
int ans, tsum;
void dfs(int cur) {
if(cur == n) {
if(tsum < ans) {
ans = tsum;
}
return ;
}
vis[cur]++;
for(int i=0; i<m; i++) if(roads[i].a == cur && visr[i] <= 3) {
int t = roads[i].r;
if(vis[roads[i].c]) t = roads[i].p;
tsum += t;
visr[i]++;
dfs(roads[i].b);
tsum -= t;
visr[i]--;
}
vis[cur]--;
}
int main() {
while(scanf("%d%d", &n, &m) != EOF) {
memset(vis, 0, sizeof(vis));
memset(visr, 0, sizeof(visr));
for(int i=0; i<m; i++) {
scanf("%d%d%d%d%d", &roads[i].a, &roads[i].b, &roads[i].c, &roads[i].p, &roads[i].r);
}
tsum = 0;
ans = INF;
dfs(1);
if(ans == INF) {
puts("impossible");
continue;
}
printf("%d\n", ans);
}
return 0;
}
标记点代码:
Accepted | 672 KB | 16 ms | G++ |
#include <stdio.h>
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <string>
#include <map>
#include <cmath>
#include <queue>
#include <set>
using namespace std;
//#define WIN
#ifdef WIN
typedef __int64 LL;
#define iform "%I64d"
#define oform "%I64d\n"
#define oform1 "%I64d"
#else
typedef long long LL;
#define iform "%lld"
#define oform "%lld\n"
#define oform1 "%lld"
#endif
#define S64I(a) scanf(iform, &(a))
#define P64I(a) printf(oform, (a))
#define S64I1(a) scanf(iform1, &(a))
#define P64I1(a) printf(oform1, (a))
#define FOR(i, s, t) for(int (i)=(s); (i)<(t); (i)++)
const int INF = 0x3f3f3f3f;
const double eps = 10e-9;
const double PI = (4.0*atan(1.0));
const int maxn = 10 + 2;
struct Road {
int a, b, c, p, r;
};
Road roads[maxn];
int vis[maxn];
int visr[maxn];
int n, m;
int ans, tsum;
void dfs(int cur) {
if(cur == n) {
if(tsum < ans) {
ans = tsum;
}
return ;
}
vis[cur]++;
for(int i=0; i<m; i++) if(roads[i].a == cur && vis[roads[i].b] <= 5) {
int t = roads[i].r;
if(vis[roads[i].c]) t = roads[i].p;
tsum += t;
visr[i]++;
dfs(roads[i].b);
tsum -= t;
visr[i]--;
}
vis[cur]--;
}
int main() {
while(scanf("%d%d", &n, &m) != EOF) {
memset(vis, 0, sizeof(vis));
memset(visr, 0, sizeof(visr));
for(int i=0; i<m; i++) {
scanf("%d%d%d%d%d", &roads[i].a, &roads[i].b, &roads[i].c, &roads[i].p, &roads[i].r);
}
tsum = 0;
ans = INF;
dfs(1);
if(ans == INF) {
puts("impossible");
continue;
}
printf("%d\n", ans);
}
return 0;
}