zoukankan      html  css  js  c++  java
  • UVA11090 Going in Cycle!!(二分判负环)

    UVA11090 Going in Cycle!!

    二分答案,用spfa判负环

    注意格式;图不一定连通。

    复杂度$O(nmlog(maxw-minw))$

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<queue>
     5 #include<cmath>
     6 #define re register
     7 using namespace std;
     8 typedef double db;
     9 const db eps=1e-7;
    10 #define N 100
    11 #define M 20000
    12 int n,m,t,ri[N]; db d[N],val[M<<1]; bool inh[N],vis[N];
    13 int cnt,hd[M],nxt[M<<1],ed[M],poi[M];
    14 void adde(int x,int y,db v){
    15     nxt[ed[x]]=++cnt; hd[x]=hd[x]?hd[x]:cnt;
    16     ed[x]=cnt; poi[cnt]=y; val[cnt]=v;
    17 }
    18 bool spfa(int st,db lim){
    19     memset(d,127,sizeof(d));
    20     memset(inh,0,sizeof(inh));
    21     memset(ri,0,sizeof(ri));
    22     queue<int> h; h.push(st);
    23     inh[st]=1; d[st]=0; vis[st]=1;
    24     while(!h.empty()){
    25         int x=h.front(); h.pop();
    26         inh[x]=0;
    27         for(int i=hd[x];i;i=nxt[i]){
    28             int to=poi[i];
    29             if(d[x]+val[i]-lim<d[to]){
    30                 d[to]=d[x]+val[i]-lim;
    31                 ri[to]=ri[x]+1; vis[to]=1;
    32                 if(ri[to]>=n) return 1;//出现次数>=n则有环
    33                 if(!inh[to])
    34                     inh[to]=1,h.push(to);
    35             }
    36         }
    37     }return 0;
    38 }
    39 bool check(db lim){
    40     memset(vis,0,sizeof(vis));
    41     bool ok=0;
    42     for(re int i=1;i<=n&&!ok;++i)
    43         if(!vis[i]) ok|=spfa(i,lim);
    44     return ok;
    45 }
    46 int main(){
    47     scanf("%d",&t); int q1,q2;db q3;
    48     for(int w=1;w<=t;++w){
    49         memset(hd,0,sizeof(hd)); cnt=0;
    50         memset(nxt,0,sizeof(nxt));
    51         memset(ed,0,sizeof(ed));
    52         scanf("%d%d",&n,&m);
    53         db l=1e8,r=-1e8;
    54         for(re int i=1;i<=m;++i){
    55             scanf("%d%d%lf",&q1,&q2,&q3);
    56             adde(q1,q2,q3);
    57             l=min(q3,l);
    58             r=max(q3,r);
    59         }printf("Case #%d: ",w);
    60         if(!check(r+1))//如果减去最大边+1仍无负环,这个图就是无环图
    61             {printf("No cycle found.
    "); continue;}
    62         while(fabs(r-l)>eps){//二分
    63             db mid=(l+r)/2.0;
    64             if(check(mid)) r=mid;
    65             else l=mid;
    66         }printf("%.2lf
    ",l);
    67     }return 0;
    68 }
    View Code
  • 相关阅读:
    页面的三大家族
    封装函数
    图片自动播放的案例
    动画封装
    长图滚动案例+点名册案例
    时钟案例
    伪随机数,随机数种子seed
    numpy.tolist( )函数
    countif( ) 函数判断当前单元格的身份证号码是否重复出现
    Excel技巧
  • 原文地址:https://www.cnblogs.com/kafuuchino/p/9836993.html
Copyright © 2011-2022 走看看