poj 1724

来源:互联网 发布:软件开发个人年终总结 编辑:程序博客网 时间:2024/06/05 16:17

这题需要剪枝

到达某个城市c的路径有许多条,可能会有一些花的钱相同但路径不同的路线。

也就是说 我们走到城市c只花了m1的钱,从另一条路走到c却花了多余m1的钱,

那么这条路没有必要继续走下去,要么到不了,要么路径长度和之前的路是一样的,

总之不会小于那个花钱少的路线

#include <iostream>#include <vector>#include <algorithm>#include <cstring>using namespace std;int K, N, R;struct Road {int end, length, cost;};vector<vector<Road> > city(105);const int INF = 1 << 30;int ans;int totalLen;int totalcost;bool vis[105];int midL[105][10005];//midL[i][j] 表示 到达i城市时花费路费为j所走的最短路径void dfs(int n){if (n == N){ans = min(ans, totalLen);return;}int size = city[n].size();for (int i = 0; i < size; ++i){int e = city[n][i].end;if (!vis[e]){int cost = totalcost + city[n][i].cost;if (cost > K)continue;int len = totalLen + city[n][i].length;if (len >= ans || len >= midL[e][cost])continue;totalcost = cost;totalLen = len;midL[e][cost] = len;vis[e] = true;dfs(e);vis[e] = false;totalLen -= city[n][i].length;totalcost -= city[n][i].cost;}}}int main(){freopen("in.txt", "r", stdin);freopen("out.txt", "w", stdout);ios::sync_with_stdio(false);int s;Road t;while (cin >> K >> N >> R){//memset(midL, INF, sizeof(midL));for (int i = 0; i < 105; ++i)for (int j = 0; j < 10005; ++j)midL[i][j] = INF;memset(vis, false, sizeof(vis));ans = INF;totalcost = 0;totalLen = 0;vis[1] = true;for (int i = 0; i < R; ++i){cin >> s >> t.end >> t.length >> t.cost;if (s != t.end){city[s].push_back(t);}}dfs(1);if (ans != INF)cout << ans << endl;elsecout << -1 << endl;}return 0;}


原创粉丝点击