您的位置:首页 > 其它

POJ-3621 Sightseeing Cows 01分数(参数搜索)规划问题-最优比率环

2013-05-24 18:13 543 查看
题意:给定N个点,M条单向边,问在图中寻找一条回路,使得该路径上的所有点权和除以边权和最大。

解法:设某点点权为ai, 边权为bi。选择某点的同时就意味着选择了某条边,那么我们把这条单向边划给弧头,因此可以得到表达式

,s是牛选择的出发点。可以利用01分数规划的一般解法来求解,那就是选择某个比例进行合法性判定,如果这个比例能够达到,则把比例加大,如果不能的话,缩小这个比例,所以也叫做参数搜索,假设这个比例为R后,上式变为

是否成立的判定问题。由于一个图中的某条回路小于0可以用spfa进行判定,那么我们就可以得到一个非常接近正确答案的值,只要精度够高,就能够保证得到的答案取两位后能够与等于0的参数R相同。另外此题还有一些不明白的地方,那就是为什么从1开始搜索一定能够找遍所有负环的可能。

代码如下:

#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;

int N, M;
const double eps = 1e-6;

struct Edge {
int v, next, ct;
}e[5005];
int idx, head[1005];
int fee[1005];

void insert(int a, int b, int c) {
e[idx].v = b, e[idx].ct = c;
e[idx].next = head[a];
head[a] = idx++;
}

int sign(double x) {
return x < -eps ? -1 : x > eps;
}

const int MaxN = 1005;
int que[1005];
int front, tail;
char vis[1005];
int cnt[1005];
double dis[1005];

double cost(int x, int y, double r) {
return r * e[y].ct - fee[x];
}

bool Ac(double x) {
fill(dis, dis+MaxN, 1e9);
memset(vis, 0, sizeof (vis));
memset(cnt, 0, sizeof (cnt));
dis[1] = 0, vis[1] = 1;
front = tail = 0;
que[tail++] = 1;
while (front != tail) {
int v, u = que[(front++)%MaxN];
double ct;
vis[u] = 0;
for (int i = head[u]; ~i; i = e[i].next) {
v = e[i].v, ct = cost(u, i, x);
if (sign(dis[u]+ct-dis[v]) < 0) {
dis[v] = dis[u] + ct;
if (!vis[v]) {
vis[v] = 1, ++cnt[v];
if (cnt[v] >= N) return true;
que[(tail++)%MaxN] = v;
}
}
}
}
return false;
}

double bsearch(double l, double r) {
double mid, ret = 0;
while (sign(r-l) >= 0) {
mid = (l + r) / 2.0; // 枚举一个参数
if (Ac(mid)) { // 如果找到负环
ret = mid;
l = mid + eps;
} else {
r = mid - eps;
}
}
return ret;
}

int main() {
int a, b, c;
while (scanf("%d %d", &N, &M) != EOF) {
idx = 0;
memset(head, 0xff, sizeof (head));
for (int i = 1; i <= N; ++i) {
scanf("%d", &fee[i]); // 读入N各点的费用
}
for (int i = 1; i <= M; ++i) { // M条单向边
scanf("%d %d %d", &a, &b, &c);
insert(a, b, c);
}
printf("%.2f\n", bsearch(0, 2000));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: