Posted on 2008-06-03 15:45
oyjpart 阅读(3112)
评论(14) 编辑 收藏 引用 所属分类:
ACM/ICPC或其他比赛
上次百度之星第三题竟然不会做,很是惭愧啊,脑袋生锈了。
后来从HUST上面找了道类似的题目,AC了。
The perfect hamilton path
Time Limit: 5 Sec Memory Limit: 128 MB
Submissions: 72 Solved: 16
Description
There
are N(2 <= N <= 13) cities and M bidirectional roads among the
cities. There exist at most one road between any pair of the cities.
Along every road, there are G pretty girls and B pretty boys(1 <=
G,B <= 1000).
You want to visit every city exactly once, and you can start from any
city you want to. The degree of satisfaction is the ratio of the number
of the pretty girls to the number of the pretty boys. You want to know
the highest degree of satisfation.
Input
There are multiply test cases.
First line: two integers N, M;
The following M lines: every line with four integers i, j, G, B, response that there is a road between i and j with G and B.
Output
The highest degree of the satisfation, rounded to the third place after the decimal point.
Sample Input
3 3
1 2 5 3
2 3 7 4
3 1 13 11
Sample Output
1.714
HINT
Source
dupeng
题目的意思是找到一个sigma(G)/sigma(B)最大的hamilton回路。
典型的参数搜索。二分或者迭代答案就可以了。
Solution:
#include <stdio.h>
#include <queue>
#include <cmath>
using namespace std;
const double EPS = 1e-4;
const int N = 15;
const int M = N * N;
#define Max(a, b) (a>b?a:b)
inline int dblcmp(double a, double b) {
if(fabs(a-b) < EPS) return 0;
return a < b ? -1 : 1;
}
struct Node
{
int x, mask;
double s;
Node() {}
Node(int mm, int xx, double ss) {
x = xx;
mask = mm;
s = ss;
}
};
int n, m;
double adj[N][N];
int X[M], Y[M], G[M], B[M];
double dp[1<<N][N];
double go(double ans) {
int i, j;
for(i = 0; i < n; ++i) {
adj[i][i] = 0;
for(j = i+1; j < n; ++j) {
adj[i][j] = adj[j][i] = -10e300;
}
}
for(i = 0; i < m; ++i) {
adj[X[i]-1][Y[i]-1] = G[i]-ans * B[i];
adj[Y[i]-1][X[i]-1] = adj[X[i]-1][Y[i]-1];
}
for(i = 0; i < (1<<n); ++i) {
for(j = 0; j < n; ++j)
dp[i][j] = -10e100;
}
queue<Node> Q;
for(i = 0; i < n; ++i) {
Q.push(Node(1<<i, i, 0.0));
dp[1<<i][i] = 0;
}
while(Q.size()) {
int f = Q.front().mask, x = Q.front().x;
double s = Q.front().s;
double& d = dp[f][x];
Q.pop();
if(s < d) continue;
for(i = 0; i < n; ++i) if((f&(1<<i)) == 0) {
if(dp[f|1<<i][i] < s + adj[x][i]) {
dp[f|1<<i][i] = s + adj[x][i];
Q.push(Node(f|1<<i, i, s + adj[x][i]));
}
}
}
double max = -10e100;
for(i = 0; i < n; ++i) {
max = Max(max, dp[(1<<n)-1][i]);
}
return max;
}
int main()
{
// freopen("t.in", "r", stdin);
int i;
double ans;
while(scanf("%d %d", &n, &m) != EOF) {
double min = 2000, max = 0;
for(i = 0; i < m; ++i) {
scanf("%d %d %d %d", &X[i], &Y[i], &G[i], &B[i]);
if(B[i] < min) min = B[i];
if(G[i] > max) max = G[i];
}
double lo = 0, hi = max/min;
int ok = 0;
for(i = 0; ; ++i) {
double mid = lo + (hi-lo)/2;
if(dblcmp((ans=go(mid)), 0.0) > 0) {
lo = mid;
} else if(dblcmp(ans, 0.0) == 0) {
printf("%.3lf\n", mid);
ok = 1;
break;
} else {
hi = mid;
}
}
if(!ok) { int a = 0; a = 1/a; }
}
return 0;
}