• hdu 3622 二分+2-sat


    算是比较经典的题目了,精度要适当高一些不然会WA。

      1 #include <algorithm>
      2 #include <iostream>
      3 #include <cstring>
      4 #include <cstdio>
      5 #include <cmath>
      6 using namespace std;
      7 
      8 const double eps = 1e-5;
      9 const int N = 200;
     10 const int M = 500000;
     11 double dis[N][N];
     12 int head[N];
     13 int s[N];
     14 bool mark[N];
     15 int n, e, c;
     16 
     17 struct Edge
     18 {
     19     int v, next;
     20 } edge[M];
     21 
     22 void addEdge( int u, int v )
     23 {
     24     edge[e].v = v;
     25     edge[e].next = head[u];
     26     head[u] = e++;
     27 }
     28 
     29 void init()
     30 {
     31     e = 0;
     32     memset( head, -1, sizeof(head) );
     33 }
     34 
     35 bool dfs( int u )
     36 {
     37     if ( mark[u ^ 1] ) return false;
     38     if ( mark[u] ) return true;
     39     mark[u] = true;
     40     s[c++] = u;
     41     for ( int i = head[u]; i != -1; i = edge[i].next )
     42     {
     43         int v = edge[i].v;
     44         if ( !dfs(v) ) return false;
     45     }
     46     return true;
     47 }
     48 
     49 bool solve()
     50 {
     51     memset( mark, false, sizeof(mark) );
     52     for ( int i = 0; i < n; i += 2 )
     53     {
     54         if ( !mark[i] && !mark[i + 1] )
     55         {
     56             c = 0;
     57             if ( !dfs(i) )
     58             {
     59                 while ( c )
     60                 {
     61                     c--;
     62                     mark[s[c]] = false;
     63                 }
     64                 if ( !dfs( i + 1 ) ) return false;
     65             }
     66         }
     67     }
     68     return true;
     69 }
     70 
     71 struct Point 
     72 {
     73     int x, y;
     74 } p[N];
     75 
     76 double cal( Point a, Point b )
     77 {
     78     return sqrt( ( a.x - b.x ) * ( a.x - b.x ) + ( a.y - b.y ) * ( a.y - b.y ) );
     79 }
     80 
     81 int main ()
     82 {
     83     while ( scanf("%d", &n) != EOF )
     84     {
     85         n = n << 1;
     86         for ( int i = 0; i < n; i++ )
     87         {
     88             scanf("%d%d", &p[i].x, &p[i].y);
     89         }
     90         for ( int i = 0; i < n; i++ )
     91         {
     92             for ( int j = i + 1; j < n; j++ )
     93             {
     94                 dis[i][j] = cal( p[i], p[j] );
     95             }
     96         }
     97         double lb = 0, ub = 1e8;
     98         while ( lb + eps < ub )
     99         {
    100             init();
    101             double mid = ( lb + ub ) / 2.0;
    102             for ( int i = 0; i < n; i++ )
    103             {
    104                 for ( int j = i + 1; j < n; j++ )
    105                 {
    106                     if ( ( i ^ 1 ) == j ) continue;
    107                     if ( 2.0 * mid > eps + dis[i][j] )
    108                     {
    109                         addEdge( i, j ^ 1 );
    110                         addEdge( j, i ^ 1 );
    111                     }
    112                 }
    113             }
    114             if ( solve() )
    115             {
    116                 lb = mid;
    117             }
    118             else
    119             {
    120                 ub = mid - eps;
    121             }
    122         }
    123         printf("%.2lf
    ", lb);
    124     }
    125     return 0;
    126 }
  • 相关阅读:
    Spring.NET学习笔记
    开源项目地址
    委托的实现匿名函数和朗姆达表达式
    c#事件与委托
    c# 时间戳转换
    List 排序
    DDD的好文章
    【转】理解JMeter聚合报告(Aggregate Report)
    【转】JMeter 通过 JDBC 访问 Oracle 和 MySQL
    【转】使用JMeter测试你的EJB
  • 原文地址:https://www.cnblogs.com/huoxiayu/p/4752308.html
Copyright © 2020-2023  润新知