P1768 天路(有向图环)

Posted Harris-H

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P1768 天路(有向图环)相关的知识,希望对你有一定的参考价值。

P1768 天路(有向图环)

找到所有环的 最大的 s u m v s u m p \\dfracsum_vsum_p sumpsumv

转化为差分约束问题。

然后用spfa判负环,确定是否有解。

注意本题用dfs 跑spfa,bfs跑会t。

卡常qwq

#include<bits/stdc++.h>
using namespace std;
const int maxn=7007;
struct edge

    int to,v,c;
;
vector<edge>G[maxn];
int n,m;
bool vis[maxn];
double dis[maxn];
bool spfa(double ans,int now)//DFS版的SPFA

    vis[now]=true;
    for(int i=0;i<G[now].size();i++)
    
        edge e=G[now][i];
        double x=ans*e.c-e.v;//边的权值,根据二分出来的ans进行修改
        if (dis[e.to]>dis[now]+x)
        
            if (vis[e.to]) return false;
            else
            
                dis[e.to]=dis[now]+x;
                vis[now]=true;
                if (!spfa(ans,e.to)) return false;
            
        
    
    vis[now]=false;//记得要回溯
    return true;

const double eps = 1e-3;
const int inf = 0x3f3f3f3f;
int main()

    scanf("%d %d ",&n,&m);
    for(int i=1;i<=m;i++)
    
        int x,y,v,c;
        scanf("%d %d %d %d",&x,&y,&v,&c);
        G[x].push_back((edge)y,v,c);
    
    for(int i=1;i<=n;i++)
    
        G[0].push_back((edge)i,0,0);//超级点与每个点都需要联通
    
    double l=0,r=1000001;
    while(r-l>eps)
    
    	for(int i=1;i<=n;i++) dis[i]=inf,vis[i]=false;
        dis[0]=0;vis[0]=true;
        double mid=(l+r)/2;
        if (spfa(mid,0)) r=mid;
        else l=mid;
        mid=(l+r)/2;
    
    if (l==0) printf("-1\\n");
    else printf("%.1f\\n",l);
    return 0;

与50位技术专家面对面 20年技术见证,附赠技术全景图

以上是关于P1768 天路(有向图环)的主要内容,如果未能解决你的问题,请参考以下文章

luogu P1768 天路

[P1768]天路(分数规划+SPFA判负环)

有向图求最小环

POJ 1734 无向图最小环/有向图最小环

判断无向图/有向图中是否存在环

有向图和无向图的环检测