[HDU3691][含读书笔记] 随机算法的胜利

[HDU3691][含读书笔记] 随机算法的胜利
昨天在老图,借得一本随机算法的书,乍一看目录,卧槽,NB了,什么都能随机……果断借走……
第一章介绍了蒙特卡罗算法和拉斯维加斯算法,Qsort就是拉斯维加斯算法,随机的结果只影响程序速度;而下面这个题,无源无汇的最小割,则是蒙特卡罗算法……随机的结果都不见得对,但是,多随机几次,得到最优解的概率会增大不少

算法很简单,在图中随机选择一条边,并将他们连接的顶点(顶点集合更为妥当……)合并,直到只剩下两个顶点集合,则这两个集合间的边至少是个割………多次随机则应该就能得到最小割了……
每次得到最小割的概率,书上证明是 2/n^2 ,可以说是相当之小……利用高等数学的知识,找不到的概率应该是1-2/n^2,于是乎,执行N^2/2次,还找不到答案的概率就是1/e……而每次随机一条边大概是O(M)的级别吧……整个算法大概是O(n*n*m)的(确切说是omega,一定是这么多次),还不保证对……

想起AC哥说过,去年FZU的B,HDU3691是这么个题,于是搞了搞,轻松拍完,样例无压力过了……之后各种TLE……毕竟300*300*50000还是压力较大的……然后各种调整随机次数,期间翻译至java……仍然TLE……一怒之下,把随机次数调整成了N次,至少能WA了……C++版本需要2400+MS,java版本需要1700+MS……(java版程序套用了我的java模板,IO是类似getchar的优化,C++是scanf,可见数据之WS……)于是把java版程序的随机次数改成5*N次,居然过了……

现在想来,数据可能水了;也可能书上理论证明的时候,放缩的太厉害,然后几百次方之后,正确率实际上比理论计算会高出很多……
无代码无真相

  1  import  java.util. * ;
  2  import  java.io. * ;
  3  import  java.math. * ;
  4 
  5 
  6  public   class  HDU3691 {
  7       public   static   void  main(String args[])  throws  IOException {
  8           new  Prob().solve();
  9      }
 10  }
 11 
 12  class  Prob {
 13       int [] f  =   new   int [ 50010 ];
 14       int [] t  =   new   int [ 50010 ];
 15       int [] c  =   new   int [ 50010 ];
 16       int [] fa  =   new   int [ 310 ];
 17       int  n,m,tot;
 18       int  ans;
 19      Random rand  =   new  Random();
 20      
 21       int  find( int  x) {
 22           if  (x  ==  fa[x])  return  x;
 23           return  fa[x]  =  find(fa[x]);
 24      }
 25 
 26       void  change( int  x, int  y) {
 27          x  =  find(x);
 28          y  =  find(y);
 29          fa[x]  =  y;
 30      }
 31      
 32       int  work() {
 33           for  ( int  i  =   1 ; i  <=  n; i ++ ) {
 34              fa[i]  =  i;
 35          }
 36           int  cnt  =  n;
 37           while  (cnt  >   2 ) {
 38               int  now  =  rand.nextInt(tot);
 39               if  (find(f[now])  ==  find(t[now])) {
 40                   int  tmp  =  f[now]; f[now]  =  f[tot - 1 ]; f[tot - 1 =  tmp;
 41                  tmp  =  t[now]; t[now]  =  t[tot - 1 ]; t[tot - 1 =  tmp;
 42                  tmp  =  c[now]; c[now]  =  c[tot - 1 ]; c[tot - 1 =  tmp;
 43                  tot  -- ;
 44              }  else  {
 45                  cnt  -- ;
 46                  change(f[now],t[now]);
 47              }
 48          }
 49           int  ans  =   0 ;
 50           for  ( int  i  =   0 ; i  <  m; i ++ ) {
 51               if  (find(f[i]) != find(t[i])) {
 52                  ans  +=  c[i];
 53              }
 54          }
 55           return  ans;
 56      }
 57 
 58       final   int  TIMES  = 5 ;    
 59      
 60       void  solve()  throws  IOException {
 61          MyReader in  =   new  MyReader();
 62           for  (;;) {
 63              n  =  in.nextInt();
 64              m  =  in.nextInt();
 65              tot  =  in.nextInt();
 66               if  (n  +  m  +  tot  ==   0 break ;
 67               for  ( int  i  =   0 ; i  <  m; i ++ ) {
 68                  f[i]  =  in.nextInt();
 69                  t[i]  =  in.nextInt();
 70                  c[i]  =  in.nextInt();
 71              }
 72              ans  =   0x7fffffff ;
 73               int  times  =  TIMES  *  n ;
 74               while  (times --   >   0 ) {
 75                  tot  =  m;
 76                   int  tmp  =  work();
 77                   if  (tmp  <  ans) {
 78                      ans  =  tmp;
 79                  }
 80              }
 81              System.out.println(ans);
 82          }
 83      }
 84       void  debug(Objectx) {
 85          System.out.println(Arrays.deepToString(x));
 86      }
 87  }
 88 
 89  class  MyReader {
 90      BufferedReader br  =   new  BufferedReader (
 91               new  InputStreamReader (System.in));
 92      StringTokenizer in;
 93      String next()  throws  IOException {
 94           if  (in  ==   null   ||   ! in.hasMoreTokens()) {
 95              in  =   new  StringTokenizer(br.readLine());
 96          }
 97           return  in.nextToken();
 98      }
 99       int  nextInt()  throws  IOException {
100           return  Integer.parseInt(next());
101      }
102  }




你可能感兴趣的:([HDU3691][含读书笔记] 随机算法的胜利)