昨天写好的直接关掉浏览器了没发出去。。
貌似思路很简单?1A。。不过我一开始想的是搜索,有环这个不好判断,而且有可能会多次走环,所以搜索的“最优”性无法体现。把边权赋值为当前从a点到b点换钱之后的价格,用Bellman-Ford算法来找正环。本来bellman是用来找负环,初始化是边权无穷大,而在这里,求可以无限松弛的最大边权路径,故,把边权初始化为无穷小,以正环代表可以挣钱,负环代表赔钱。
#include<iostream> using namespace std; int n; int m; int s; double v; int all; double dis[101]; struct exchange_points { int a; //货币a int b; //货币b double ratio; double costs; }exc[202]; bool bellman() { memset(dis, 0, sizeof(dis)); //这里与bellman的目的刚好相反。初始化为源点到各点距离无穷小 dis[s] = v; //即bellman本用于找负环,求最小路径,本题是利用同样的思想找正环,求最大路径 bool flag; for (int i = 1; i <= n - 1; i++) { flag = false; for (int j = 0; j<all; j++) if (dis[exc[j].b] < (dis[exc[j].a] - exc[j].costs) * exc[j].ratio) //寻找最长路径 { //进行比较的是"某点到自身的权值"和"某点到另一点的权值" dis[exc[j].b] = (dis[exc[j].a] - exc[j].costs) * exc[j].ratio; flag = true; } if (!flag) break; } for (int k = 0; k<all; k++) if (dis[exc[k].b] < (dis[exc[k].a] - exc[k].costs) * exc[k].ratio) //正环能够无限松弛 return true; return false; } int main(void) { int a, b; double rab, cab, rba, cba; while (cin >> n >> m >> s >> v) { all = 0; for (int i = 0; i < m; i++) { cin >> a >> b >> rab >> cab >> rba >> cba; exc[all].a = a; exc[all].b = b; exc[all].ratio = rab; exc[all++].costs = cab; exc[all].a = b; exc[all].b = a; exc[all].ratio = rba; exc[all++].costs = cba; } if (bellman()) cout << "YES" << endl; else cout << "NO" << endl; } return 0; } |