经典题。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define maxn 110
#define inf 0x3f3f3f3f
struct Node {
int price, level, down;
} G[maxn];
int head[maxn], m, n, id;
struct Node2 {
int v, val, next;
} E[maxn * maxn];
bool vis[maxn];
int sta[maxn], id2; // sta防止间接等级越界
void addEdge(int u, int v, int val) {
E[id].v = v; E[id].next = head[u];
E[id].val = val; head[u] = id++;
}
int min(int a, int b) {
return a < b ? a : b;
}
int DFS(int u) {
for(int i = 0; i < id2; ++i)
if(abs(sta[i] - G[u].level) > m)
return inf;
int v, ans = G[u].price;
for(int i = head[u]; i != -1; i = E[i].next) {
if(vis[v = E[i].v]) return inf;
vis[v] = 1; sta[id2++] = G[u].level;
ans = min(ans, E[i].val + DFS(v));
vis[v] = 0; --id2;
}
return ans;
}
int solve() {
memset(vis, 0, sizeof(bool) * (n + 1));
int i, j, v, ans = G[1].price; vis[1] = 1;
id2 = 0; sta[id2++] = G[1].level;
for(i = head[1]; i != -1; i = E[i].next) {
v = E[i].v;
ans = min(ans, E[i].val + DFS(v));
}
return ans;
}
int main() {
int i, j, v, val;
while(scanf("%d%d", &m, &n) == 2) {
memset(head, -1, (n + 1) * sizeof(int));
for(i = 1, id = 0; i <= n; ++i) {
scanf("%d%d%d", &G[i].price, &G[i].level, &G[i].down);
for(j = 0; j < G[i].down; ++j) {
scanf("%d%d", &v, &val);
addEdge(i, v, val);
}
}
printf("%d\n", solve());
}
return 0;
}
2015.2.7更新
#include <stdio.h>
#include <string.h>
#define inf 0x3f3f3f3f
#define maxn 110
struct Node {
int P, L, X; // 价格、主人等级、替代品数
} goods[maxn];
struct Node2 {
int T, V; // 编号、价格优惠
} substi[maxn][maxn];
int M, N;
bool vis[maxn];
int min(int a, int b) { return a < b ? a : b; }int max(int a, int b) { return a > b ? a : b; }int solve(int numOfGoods, int minLevel, int maxLevel) { if (maxLevel - minLevel > M) return inf; int tempNumOfGoods, minL, maxL, i; int result = goods[numOfGoods].P; for (i = 1; i <= goods[numOfGoods].X; ++i) { tempNumOfGoods = substi[numOfGoods][i].T; if (vis[tempNumOfGoods]) continue; vis[tempNumOfGoods] = true; minL = min(minLevel, goods[tempNumOfGoods].L); maxL = max(maxLevel, goods[tempNumOfGoods].L); result = min(result, solve(tempNumOfGoods, minL, maxL) + substi[numOfGoods][i].V); vis[tempNumOfGoods] = false; } return result;}int main() { // freopen("data.in", "r", stdin); int i, j; while (scanf("%d%d", &M, &N) == 2) { memset(vis, 0, sizeof(vis)); for (i = 1; i <= N; ++i) { scanf("%d%d%d", &goods[i].P, &goods[i].L, &goods[i].X); for (j = 1; j <= goods[i].X; ++j) scanf("%d%d", &substi[i][j].T, &substi[i][j].V); } printf("%d\n", solve(1, goods[1].L, goods[1].L)); } return 0;}
2015.04.13更新
#include <stdio.h>
#include <string.h>
const int maxn = 110;
const int inf = 0x3f3f3f3f;
int head[maxn], id;
struct Node {
int v, w, next;
} E[maxn*maxn];
struct Node2 {
int price, level;
} Per[maxn];
int N, M, dp[maxn]; // N articles
int min(int a, int b) { return a < b ? a : b; }
int max(int a, int b) { return a > b ? a : b; }
void addEdge(int u, int v, int w)
{
E[id].v = v;
E[id].w = w;
E[id].next = head[u];
head[u] = id++;
}
void getMap()
{
int i, j, P, L, K, w, v;
memset(head, -1, sizeof(head));
memset(dp, 0, sizeof(dp));
for (id = 0, i = 1; i <= N; ++i) {
scanf("%d%d%d", &P, &L, &K);
Per[i].price = P;
Per[i].level = L;
while (K--) {
scanf("%d%d", &v, &w);
addEdge(i, v, w);
}
}
}
int findMinCost(int k, int maxLevel, int minLevel)
{
maxLevel = max(maxLevel, Per[k].level);
minLevel = min(minLevel, Per[k].level);
if (maxLevel - minLevel > M)
return inf;
else if (dp[k]) return dp[k];
int ret = Per[k].price;
int i, v;
dp[k] = Per[k].price;
for (i = head[k]; i != -1; i = E[i].next) {
v = E[i].v;
dp[k] = min(dp[k], findMinCost(v, maxLevel, minLevel) + E[i].w);
}
return dp[k];
}
int solve()
{
return findMinCost(1, Per[1].level, Per[1].level);
}
int main()
{
while (~scanf("%d%d", &M, &N)) {
getMap();
printf("%d\n", solve());
}
return 0;
}