基本参数搜索

上次百度之星第三题竟然不会做,很是惭愧啊,脑袋生锈了。

后来从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 ;
}

 


你可能感兴趣的:(基本参数搜索)