zoukankan      html  css  js  c++  java
  • UVa 11090 Going in Cycle!!【Bellman_Ford】

    题意:给出n个点m条边的加权有向图,求平均值最小的回路

    自己想的是用DFS找环(真是too young),在比较找到各个环的平均权值,可是代码实现不了,觉得又不太对

    后来看书= =好巧妙的办法, 使用二分法求解,首先记录下来这m条边的最大权值ub

    然后可以猜测一个mid,只需要判断是否存在平均值小于mid的回路 假设存在一个包含k条边的回路,回路上各条边的权值分别为w1,w,2,w3,----,wk

    那么

    w1+w2+w3+----+wk<k*mid

    又因为联想到Bellman_Ford可以解决负环,把上式转化一下

    (w1-mid)+(w2-mid)+(w3-mid)+----(wk-mid)<0

    这样先将每条边w(a,b)转化成为w(a,b)-mid,再判断“新”的图中是否存在负环

    自己看的时候有两个不明白的,就是最开始判断的时候为什么要用ub+1,

    是因为ub+1是最差的答案了,它能够尽可能的使得每条边负得最多,如果在这种情况下都找不到负环,那么一定不存在负环

    然后就是如果在ub+1的条件下能够找到负环,那么就二分查找一步步找出平均值最小的环,直到到达循环退出的精度

    代码学习的标程= =

      1 #include<iostream>  
      2 #include<cstdio>  
      3 #include<cstring> 
      4 #include <cmath> 
      5 #include<stack>
      6 #include<vector>
      7 #include<map> 
      8 #include<set>
      9 #include<queue> 
     10 #include<algorithm>  
     11 #define mod=1e9+7;
    
     12 using namespace std;
     13 
     14 typedef long long LL;
     15 const int INF = 0x7fffffff;
     16 const int maxn=10005;
     17 
     18 struct Edge{
     19     int from,to;
    
     20     double dist;
     21 };
     22 
     23 struct BellmanFord{
     24     int n,m;
     25     vector<Edge> edges;
     26     vector<int> G[maxn];
     27     bool inq[maxn];
     28     double d[maxn];
     29     int p[maxn];
     30     int cnt[maxn];
     31     
     32     void init(int n){
     33         this->n=n;
     34         for(int i=0;i<n;i++) G[i].clear();
     35         edges.clear();
     36     }
     37     
     38     void AddEdges(int from,int to,double dist){
     39         edges.push_back((Edge){from,to,dist});
     40         m=edges.size();
     41         G[from].push_back(m-1);
     42     }
     43     
     44     bool negativeCycle(){
     45         queue<int> Q;
     46         memset(inq,0,sizeof(inq));
     47         memset(cnt,0,sizeof(cnt));
     48         for(int i=0;i<n;i++) {d[i]=0;inq[0]=true;Q.push(i);}
     49         
     50         while(!Q.empty()){
     51             int u=Q.front();Q.pop();
     52             inq[u]=false;
     53             for(int i=0;i<G[u].size();i++){
     54                 Edge& e=edges[G[u][i]];
     55                 if(d[e.to]>d[u]+e.dist){
     56                     d[e.to]=d[u]+e.dist;
     57                     p[e.to]=G[u][i];
     58                     if(!inq[e.to]){
     59                         Q.push(e.to);
     60                         inq[e.to]=true;
     61                         if(++cnt[e.to]>n) 
     62                         return true;
     63                     }
     64                 }
     65             }
     66         }
     67         return false;
     68     }
     69 };
     70 
     71 BellmanFord solver;
     72 
     73 bool test(double x){
     74     for(int i=0;i<solver.m;i++)
     75     solver.edges[i].dist-=x;
     76     
     77     bool ret=solver.negativeCycle();
     78     for(int i=0;i<solver.m;i++)
     79     solver.edges[i].dist+=x;
     80     return ret;
     81 }
     82 
     83 int main(){
     84     int T;
     85     scanf("%d",&T);
     86     for(int kase=1;kase<=T;kase++){
     87         int n,m;
     88         scanf("%d %d",&n,&m);
     89         solver.init(n);
     90         int ub=0;
     91         while(m--){
     92             int u,v,w;
     93             scanf("%d %d %d",&u,&v,&w);u--;v--;ub=max(ub,w);
     94             solver.AddEdges(u,v,w);            
     95         }
     96         printf("Case #%d: ",kase);
     97         if(!test(ub+1)) printf("No cycle found.
    ");
     98         else{
     99             double L=0,R=ub;
    100             while(R-L>1e-3){
    101                 double M=L+(R-L)/2;
    102                 if(test(M)) R=M;else L=M;
    103             }
    104             printf("%.2lf
    ",L);
    105         }
    106     }
    107     return 0;
    108 }
    View Code
  • 相关阅读:
    常用 SQL Server 规范集锦
    让Git忽略所有obj和bin目录的同步
    Sql server 存储过程基础语法
    nginx 站点代理,负载均衡
    CentOS7.0安装Nginx-1.12.0
    CentOS7安装GNOME可视化界面和如何配置IP地址
    开发工具资料集合
    NOIP2018总结反思
    NOIP2018考试报告
    STL基础用法
  • 原文地址:https://www.cnblogs.com/wuyuewoniu/p/4417576.html
Copyright © 2011-2022 走看看