训练指南 UVA - 11090(最短路BellmanFord+ 二分判负环)



layout: post
title: 训练指南 UVA - 11090(最短路BellmanFord+ 二分判负环)
author: "luowentaoaa"
catalog: true
mathjax: true
tags:
- 最短路
- 基础DP
- BellmanFord
- 图论
- 训练指南



Going in Cycle!!

UVA - 11090

题意

就最小的环的平均权值

题解

分枚举平均值mid,只需判断是否存在平均值小于mid的回路,即判断是否有sum(wi)<mid*k (1≤i≤k),只需判断是否有sum(wi-mid)<0,只需将边权值减去mid后,判断是否存在负环。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=998244353;
const int maxn=1e3+10;
const int inf=1000000000;
struct Edge
{
    int from, to;
    double dist;
    Edge() {}
    Edge(int u, int v, double d) : from(u), to(v), dist(d) {}
};
struct BellmanFord{
    int n,m;
    vector<Edge>edges;
    vector<int> G[maxn];
    bool inq[maxn]; /// 是否在队列中
    double d[maxn];    /// s到各个点的距离  double 要改成double类型
    int p[maxn];    /// 最短路中的上一条弧
    int cnt[maxn];  /// 进队次数
    void init(int n){
        this->n=n;
        for(int i=0;i<n;i++)G[i].clear();
        edges.clear();
    }
    void AddEdge(int from, int to, int dist)
    {
        edges.emplace_back(from, to, dist);
        m = edges.size();
        G[from].push_back(m - 1);
    }
    bool bellmanford(int s){
        queue<int>Q;
        memset(inq,0,sizeof(inq));
        memset(cnt,0,sizeof(cnt));
        for(int i = 0; i < n; i++) { d[i] = 0; inq[0] = true; Q.push(i); } //如果只判负环用这个
        /*for(int i=0;i<n;i++)d[i]=inf;
        d[s]=0;inq[s]=true;Q.push(s);*/
        while(!Q.empty()){
            int u=Q.front();
            Q.pop();
            inq[u]=false;
            for(auto& id:G[u]){
                Edge& e=edges[id];
                if(d[u]<inf && d[e.to]>d[u]+e.dist){
                    d[e.to]=d[u] + e.dist;
                    p[e.to]=id;
                    if(!inq[e.to]){
                        Q.push(e.to);
                        inq[e.to]=true;
                        if(++cnt[e.to]>n)return true;
                    }
                }
            }
        }
        return false;
    }
};
BellmanFord solver;
bool test(double x){
    for(int i=0;i<solver.m;i++)
        solver.edges[i].dist-=x;
    bool ret=solver.bellmanford(0);
    for(int i=0;i<solver.m;i++)
        solver.edges[i].dist+=x;
    return ret;
}
int main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    std::cout.tie(0);
    int t;
    scanf("%d",&t);
    for(int kase=1;kase<=t;kase++){
        int n,m;
        scanf("%d%d",&n,&m);
        solver.init(n);
        int ub=0;
        while(m--){
            int u,v,w;
            scanf("%d%d%d",&u,&v,&w);u--;v--;ub=max(ub,w);
            solver.AddEdge(u,v,w);
        }
        printf("Case #%d: ", kase);
        if(!test(ub+1))printf("No cycle found.\n");
        else{
            double l=0,r=ub;
            while(r-l>1e-4){
                double mid=l+(r-l)/2;
                if(test(mid))r=mid;
                else l=mid;
            }
            printf("%.2f\n",l);
        }
    }
    return 0;
}

原文地址:https://www.cnblogs.com/luowentao/p/10348241.html

时间: 2024-10-11 12:33:34

训练指南 UVA - 11090(最短路BellmanFord+ 二分判负环)的相关文章

UVA - 11090 Going in Cycle!! (Bellman-Ford算法判负环)

Description I I U P C 2 0 06 Problem G: Going in Cycle!! Input: standard input Output: standard output You are given a weighted directed graph with n vertices and m edges. Each cycle in the graph has a weight, which equals to sum of its edges. There

BZOJ 1486 最小圈(二分+判负环)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1486 题意:给出一个有向图,边有权值.找到一个环,使得环上边的权值之和除以环上边的个数最小. 思路:二分答案x,每条边权值减去x,之后 找负环.从每个顶点开始DFS,记录到达某个顶点的距离,设当前DFS的顶点为u,距离dis[u].下一个顶点v, 权值w,则dis[u]+w<=0时才DFS(v).另外,若v是已经遍历过的,且dis[u]+w-dis[v](这个dis[v]是之前遍历时

BZOJ3597 [Scoi2014]方伯伯运椰子 【二分 + 判负环】

题目链接 BZOJ3597 题解 orz一眼过去一点思路都没有 既然是流量网络,就要借鉴网络流的思想了 我们先处理一下那个比值,显然是一个分数规划,我们二分一个\(\lambda = \frac{X - Y}{k}\) 如果\(\lambda\)成立,则 \[\lambda \le \frac{X - Y}{k}\] 即 \[\lambda k + (Y - X) \le 0\] 所以我们只需要判断是否存在一种方案使得这个式子成立 依照网络流的思想,撤回流量就往反向边走,扩展流量往正向边 对于边

uva 558 Wormholes (Bellman-Ford算法判断负环)

uva 558 Wormholes In the year 2163, wormholes were discovered. A wormhole is a subspace tunnel through space and time connecting two star systems. Wormholes have a few peculiar properties: Wormholes are one-way only. The time it takes to travel throu

训练指南 UVA - 11478(最短路BellmanFord+ 二分+ 差分约束)

layout: post title: 训练指南 UVA - 11478(最短路BellmanFord+ 二分+ 差分约束) author: "luowentaoaa" catalog: true mathjax: true tags: - 最短路 - BellmanFord - 图论 - 训练指南 - 差分约束 Halum UVA - 11478 题意 带权有向图,每个点都可以有如下操作:令从ta出发的每一条边增加d,终止于ta的每一条边减小d 最后让所有边权的最小值非负且尽量大 题

训练指南 UVA - 11374(最短路Dijkstra + 记录路径 + 模板)

layout: post title: 训练指南 UVA - 11374(最短路Dijkstra + 记录路径 + 模板) author: "luowentaoaa" catalog: true mathjax: true tags: - 最短路 - Dijkstra - 图论 - 训练指南 Airport Express UVA - 11374 题意 机场快线有经济线和商业线,现在分别给出经济线和商业线的的路线,现在只能坐一站商业线,其他坐经济线,问从起点到终点的最短用时是多少,还有

训练指南 UVA - 10917(最短路Dijkstra + 基础DP)

layout: post title: 训练指南 UVA - 10917(最短路Dijkstra + 基础DP) author: "luowentaoaa" catalog: true mathjax: true tags: - 最短路 - 基础DP - Dijkstra - 图论 - 训练指南 Walk Through the Forest UVA - 10917 题意 Jimmy打算每天沿着一条不同的路走,而且,他只能沿着满足如下条件的道路(A,B):存在一条从B出发回家的路径,比

训练指南 UVA - 11354(最小生成树 + 倍增LCA)

layout: post title: 训练指南 UVA - 11354(最小生成树 + 倍增LCA) author: "luowentaoaa" catalog: true mathjax: true tags: - 最小生成树 - LCA - 图论 - 训练指南 Bond UVA - 11354 题意 给你一张无向图,然后有若干组询问,让你输出a->b的最小瓶颈路 题解 先求出最小生成树,然后对这个最小生成树做LCA. #include<bits/stdc++.h>

训练指南 UVA - 11383(KM算法的应用 lx+ly &gt;=w(x,y))

layout: post title: 训练指南 UVA - 11383(KM算法的应用 lx+ly >=w(x,y)) author: "luowentaoaa" catalog: true mathjax: true tags: - KM算法 - 训练指南 Golden Tiger Claw UVA - 11383 题意 给一个n*n的矩阵,每个格子中有正整数w[i[j],试为每行和每列分别确定一个数字row[i]和col[i],使得任意格子w[i][j]<=row[i