zoukankan      html  css  js  c++  java
  • UVa11090 Going in Cycle!!

    UVa11090 Going in Cycle!!

    链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=34650

    【思路】

       二分+SPFA。

       二分平均值mid,如果有平均值小于mid的情况我们就缩小猜测值否则增大猜测值。如何判定?如果有平均值小于mid 则有:w1-mid+w2-mid+w3-mid+…<0 即将各条边权减mid后图中存在负圈,SPFA判负圈即可。

       需要注意把int修改为double

    【代码】

     1 #include<cstdio>
     2 #include<queue>
     3 #include<cstring> 
     4 #include<algorithm>
     5 using namespace std;
     6 
     7 const int maxn = 100+10;
     8 const double INF=1e10;
     9 struct Edge{
    10     int v,next;
    11     double w;
    12 }e[maxn*maxn];
    13 int en,front[maxn];
    14 
    15 int n,m;
    16 
    17 inline void AddEdge(int u,int v,double w) {
    18     en++; e[en].v=v; e[en].w=w; e[en].next=front[u]; front[u]=en;
    19 }
    20 
    21 bool SPFA_NC() {
    22     int inq[maxn],cnt[maxn];
    23     double d[maxn];
    24     queue<int> q;
    25     memset(cnt,0,sizeof(cnt));
    26     memset(inq,0,sizeof(inq));
    27     //添加一个超级源节点 
    28     for(int s=1;s<=n;s++)
    29     {
    30       d[s]=0; inq[s]=1; q.push(s);
    31     }
    32     while(!q.empty()) {
    33         int u=q.front(); q.pop(); inq[u]=0;
    34         for(int i=front[u];i>=0;i=e[i].next) {
    35             int v=e[i].v; double w=e[i].w;
    36             if(d[v]>d[u]+w) {
    37                 d[v]=d[u]+w;
    38                 if(!inq[v]) {
    39                     inq[v]=1;
    40                     q.push(v);
    41                     if(++cnt[v]>n+1) return true;
    42                 }
    43             }
    44         }
    45     }
    46     return false;
    47 }
    48 
    49 inline void init() {
    50     en=0;
    51     memset(front,-1,sizeof(front));
    52 }
    53 
    54 bool can(double x) {
    55     for(int i=1;i<=en;i++) e[i].w-=x;
    56     bool ans=SPFA_NC();
    57     for(int i=1;i<=en;i++) e[i].w+=x;
    58     return ans;
    59 }
    60 
    61 int main() {
    62     int T;
    63     scanf("%d",&T);
    64     for(int kase=1;kase<=T;kase++) {
    65         init();
    66         scanf("%d%d",&n,&m);
    67         double L=0,R=0;
    68         int u,v; double w;
    69         for(int i=0;i<m;i++) {
    70             scanf("%d%d%lf",&u,&v,&w);
    71             AddEdge(u,v,w);
    72             if(w>R) R=w;
    73         }
    74         printf("Case #%d: ",kase);
    75         if(!can(R+1)) printf("No cycle found.
    ");
    76         else 
    77         {
    78            while(R-L>1e-3) {
    79                 double M=L+(R-L)/2;
    80                 if(can(M)) R=M;  //存在平均值小于mid的回路 则缩小猜测值 
    81                   else L=M;
    82            }
    83            printf("%.2lf
    ",L);
    84         }
    85     }
    86     return 0;
    87 }
  • 相关阅读:
    FFT 和 NTT
    神秘构造题
    P4396 [AHOI2013]作业
    杜教筛学习笔记
    杜教筛
    「$mathcal{Darkbzoj}$」神犇和蒟蒻
    「CQOI2015」选数
    「$mathcal{Atcoder}$」$mathcal{ARC101}$
    「NOI2019」退役记???
    「李超线段树」
  • 原文地址:https://www.cnblogs.com/lidaxin/p/4909240.html
Copyright © 2011-2022 走看看