欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

spfa+01分数规划【观光奶牛】

程序员文章站 2022-05-21 19:59:18
...

spfa+01分数规划

spfa+01分数规划【观光奶牛】

思路

  • 01分数规划,二分

代码

#include<iostream>
#include<algorithm>
#include<string.h>
#include<queue>
using namespace std;
const int N=2e5;
int h[N],ne[N],wt[N],e[N],wf[N],idx;
int n,m,cnt[N];
double dis[N];
bool st[N];
void add(int a,int b,int c)
{
    e[idx]=b;
    wt[idx]=c;
    ne[idx]=h[a];
    h[a]=idx++;
}
bool check(double mid)
{
    memset(cnt,0,sizeof cnt);
    memset(st,0,sizeof st);
    queue<int>q;
    for(int i=1;i<=n;i++)
    {
        q.push(i);
        st[i]=1;
    }
    while(q.size())
    {
        int t=q.front();
        q.pop();
        st[t]=0;
        for(int i=h[t];~i;i=ne[i])
        {
            int j=e[i];
            if(dis[j]<dis[t]+wf[t]-mid*wt[i])
            {
                dis[j]=dis[t]+wf[t]-mid*wt[i];
                cnt[j]=cnt[t]+1;
                if(cnt[j]>=n) return true;
                if(st[j]==0)
                {
                    st[j]=1;
                    q.push(j);
                }
            }
        }
    }
    return false;
}
int main()
{
    cin>>n>>m;
    memset(h,-1,sizeof h);
    idx=0;
    for(int i=1;i<=n;i++) cin>>wf[i];
    for(int i=0;i<m;i++)
    {
        int a,b,c;
        cin>>a>>b>>c;
        add(a,b,c);//add(b,a,c);
    }
    double l=0,r=1e3;
    while(r-l>1e-4)
    {
        double mid=(l+r)/2;
        if(check(mid)) l=mid;
        else r=mid;
    }
    printf("%.2lf\n",r);
    return 0;
}

相关标签: 图论