题意:
n个城市,编号为1~n,他们间有m条单向路,分别从a到b,可以在c处交P路费,也可以直接交R路费。
现在从1到n,问最少的花费是多少。
解析:
每次取边的时候判断一下。
代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <stack>
#include <vector>
#include <queue>
#include <map>
#include <climits>
#include <cassert>
#define LL long long
#define lson lo, mi, rt << 1
#define rson mi + 1, hi, rt << 1 | 1
using namespace std;
const int inf = 0x3f3f3f3f;
const int maxn = 11;
int n, m;
struct Edge
{
int a, b, c, P, R;
Edge() {}
Edge(int _a, int _b, int _c, int _P, int _R)
{
a = _a;
b = _b;
c = _c;
P = _P;
R = _R;
}
};
struct State
{
int curPos, cost;
int cover;
State() {}
State(int _curPos, int _cost, int _cover)
{
curPos = _curPos;
cost = _cost;
cover = _cover;
}
bool operator < (const State& b)const
{
return cost > b.cost;
}
};
vector<Edge> edge[maxn];
bool vis[maxn][1 << maxn];
State ans;
void dijkstra()
{
priority_queue<State> q;
q.push(State(1, 0, 1 << 1));
memset(vis, false, sizeof(vis));
while (!q.empty())
{
State now = q.top();
q.pop();
if (vis[now.curPos][now.cover])
continue;
vis[now.curPos][now.cover] = true;
if (now.curPos == n)
{
ans = now;
break;
}
for (vector<Edge>::iterator it = edge[now.curPos].begin(); it != edge[now.curPos].end(); ++it)
{
Edge e = *it;
int cost = now.cost;
if (now.cover & (1 << e.c))
{
cost += min(e.P, e.R);
}
else
{
cost += e.R;
}
q.push(State(e.b, cost, now.cover | (1 << e.b)));
}
}
}
int main()
{
#ifdef LOCAL
freopen("in.txt", "r", stdin);
#endif // LOCAL
while (~scanf("%d%d", &n, &m))
{
for (int i = 0; i < m; i++)
{
int a, b, c, P, R;
scanf("%d%d%d%d%d", &a, &b, &c, &P, &R);
edge[a].push_back(Edge(a, b, c, P, R));
}
ans.cost = -1;
ans.cover = -1;
ans.curPos = -1;
dijkstra();
if (ans.curPos == -1)
{
puts("impossible");
}
else
{
printf("%d\n", ans.cost);
}
}
return 0;
}