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
  • 相关阅读:
    【纯水题】POJ 1852 Ants
    【树形DP】BZOJ 1131 Sta
    【不知道怎么分类】HDU
    【树形DP】CF 1293E Xenon's Attack on the Gangs
    【贪心算法】CF Emergency Evacuation
    【思维】UVA 11300 Spreading the Wealth
    【树形DP】NOI2003 逃学的小孩
    【树形DP】BZOJ 3829 Farmcraft
    【树形DP】JSOI BZOJ4472 salesman
    【迷宫问题】CodeForces 1292A A NEKO's Maze Game
  • 原文地址:https://www.cnblogs.com/wuyuewoniu/p/4417576.html
Copyright © 2011-2022 走看看