UVa 11090

来源:互联网 发布:涉外商标代理人 知乎 编辑:程序博客网 时间:2024/05/16 04:24

题目链接

分析:
这道题我们需要二分答案
对于一个二分出来的mid,只需要判断是否存在平均值小于mid的回路
如何判断呢?
假设存在一条回路k1,k2,k3,…kn平均值小于mid
则有:k1+k2+k3+…+kn < mid*n
移向得:k1-mid+k2-mid+…+kn-mid < 0

这样就很明了了,
我们只要把每条边的权值由w(i,j)变成w(i,j)-mid
用Bellman判断有没有负环就好了

tip

Bellman中,一开始需要把所有的点都入队

//这里写代码片#include<cstdio>#include<cstring>#include<iostream>#include<vector>#include<queue>#include<cmath>using namespace std;const double INF=1e10;const double eps=1e-10;int n,m;int dcmp(double x){    if (fabs(x)<eps) return 0;    else if (x>0) return 1;    else return -1;}struct node{    int x,y;    double v;};struct Bellman{    int n,m;    vector<node> e;    vector<int> G[100];    int pre[100];    double dis[100];    int cnt[100];    bool in[100];    void init(int n)    {        this->n=n;        e.clear();        for (int i=1;i<=n;i++) G[i].clear();    }    void add(int u,int w,double z)    {        e.push_back((node){u,w,z});        m=e.size();        G[u].push_back(m-1);    }    bool fuhuan()    {        for (int i=1;i<=n;i++) dis[i]=INF;        memset(in,0,sizeof(in));        memset(cnt,0,sizeof(cnt));        queue<int> Q;        for (int i=1;i<=n;++i)     //每个结点都要入队         {             dis[i] =0;             in[i]=1;             Q.push(i);        }        while (!Q.empty())        {            int now=Q.front(); Q.pop();            in[now]=0;            for (int i=0;i<G[now].size();i++)            {                node way=e[G[now][i]];                if (dcmp(dis[way.y]-dis[now]-way.v)>0)                {                    dis[way.y]=dis[now]+way.v;                    pre[way.y]=G[now][i];                    if (!in[way.y])                    {                        in[way.y]=1;                        Q.push(way.y);                        if (++cnt[way.y]>n) return 1;                    }                }            }        }        return 0;    }};Bellman A;int pd(double x){    for (int i=0;i<A.m;i++)        A.e[i].v-=x;    bool pp=A.fuhuan();    for (int i=0;i<A.m;i++)        A.e[i].v+=x;    return pp;}int main(){    int T;    scanf("%d",&T);    for (int cas=1;cas<=T;cas++)    {        scanf("%d%d",&n,&m);        A.init(n);        int maxx=0;        for (int i=1;i<=m;i++)        {            int u,w,z;            scanf("%d%d%d",&u,&w,&z);            maxx=max(maxx,z);            A.add(u,w,z);        }        printf("Case #%d: ",cas);        if (!pd(maxx+1)) printf("No cycle found.\n");        //如果有环,平均权值一定小于maxx+1         else        {            double l=0;            double r=maxx;            double mid;            while (r-l>1e-3)            {                mid=l+(r-l)/2;                //二分的时候有一点不同                 if (pd(mid))                    r=mid;                else l=mid;            }            printf("%.2lf\n",l);        }    }     return 0;}
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 宝宝经常不拉大便怎么办 宝宝便秘 肛裂了怎么办 3个月宝宝不便便怎么办 宝宝8个月不便便怎么办 宝宝在幼儿园不爱说话怎么办 广东学考考了d怎么办 上嘴唇干燥紧绷怎么办 美国大学gpa非常低怎么办 大学手机作弊通报教务处怎么办 崩坏3邮箱验证码过期怎么办 快递员被顾客恶意投诉怎么办 5岁幼儿逻辑思维差怎么办 脸一边胖一边瘦怎么办 夏天穿鞋子脚痒怎么办 脚痒怎么办但不是脚气 脚气脚趾缝烂了怎么办 凉鞋穿久了臭怎么办 运动鞋穿久了臭怎么办 体恤穿久了发臭怎么办 十七八岁青少年逆反心理怎么办 挨刚煮好的粥烫伤改怎么办? 5e的demo有水印怎么办 宝宝湿疹激素一停药复发怎么办 木工家装没事做怎么办 取票之后票丢了怎么办 补牙咬合低了点怎么办 留学生上美国网课上不了网怎么办 大四绩点不够2.0怎么办 ucas申请成绩下来后怎么办 在本校读研毕业东西怎么办 美国硕士gpa低于3.0怎么办 英国t4签证拒签怎么办 abc洗液过敏了怎么办 护士电子化注册忘记用户名怎么办 手机重力感应坏了怎么办 电脑所有驱动都删除了怎么办 毕业生没有签工作档案怎么办 澳洲两年工作签怎么办 上班一年没签劳动合同怎么办 公司拖欠工资怎么办没签劳动合同 brp丢了怎么办回国补