Luogu P2868 [USACO07DEC] Sightseeing Cows Problem Solution

topic

This question is a standard 01 score plan:

But there are some details that can be optimized:

It is not difficult to think of dividing a mid into two and then determine whether there is a ring S on the graph, whether the ring satisfies ∑i=1t(Fun[vi]−mid∗Tim[ei])>0

But the above algorithm is not easy to implement, so you can multiply both sides by -1 at the same time, so that the formula becomes i = 1 t ​( m i d T i m [ e i ​] F u n [ v i ​] ) < 0

Then the problem is transformed into running SPFA in each graph to find whether there is a negative cycle, if there is, l=mid, otherwise r=mid;

 

#include <bits/stdc++.h>
#define inc(a,b,c) for(register int i=a;i<=b;i+=c)
#define ini 20010
using namespace std;
int n,m;
struct littlestar{
    int from;
    int to;
    int nxt;
    double w;
}star[this],star2[this];
int head[ini],cnt,head2[ini];
void add(int u,int v,int w)
{
    star[++cnt].to=v;
    star[cnt].nxt=head[u];
    star[cnt].from=u;
    star[cnt].w=w;
    head[u]=cnt;
}
int c[this];
queue<int> q;
double dis[ini];
int vis[ini];
int SPFA()
{
    int tot=0;
    for(int i=1;i<=n;i++){
        q.push(i);
        dis [i] = 0 ;
        show [i] = 1 ;
    }
    while(q.size()){
        int u=q.front();
        q.pop();
        vis[u]=0;
        for(int i=head2[u];i;i=star2[i].nxt){
            int v=star2[i].to;
            if(dis[v]>dis[u]+star2[i].w){
                dis[v]=dis[u]+star2[i].w;
                if(vis[v]==0){
                    force[v] = 1 ;
                    q.push(v);
                    ++tot;
                    if(tot>2*(n+m)) return 0;
                }
            }
        }
    }
    return 1;
}
int check(double x)
{
    inc(1,cnt,1){
        star2[i]=star[i];
        star2[i].w=(double)star[i].w*(double)x-(double)c[star[i].from];
    }
    inc(1,n,1){
        head2[i]=head[i];
    }
    if(SPFA()){
        return 0;
    }
    else{
        return 1;
    }
}
int read()
{
    int x=0,f=1; char ch=getchar();
    while(ch<'0'||ch>'9'){
    if(ch=='-')f=-1; ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();}
    return x*f;
    
}
intmain ()
{
    n=read();
    m=read();
    inc(1,n,1) c[i]=read();
    inc(1,m,1){
        int u,v,w;
        u=read();v=read();w=read();
        add(u,v,w);
    }
    double l=0.00,r=1000010.000,mid;
    while(r-l>1e-4){
        mid=(l+r)/2;
        if(check(mid)){
            l=mid;
        }
        else{
            r=mid;
        }    
    }
    printf("%.2lf",l);
}

 

Reprinted in: https://www.cnblogs.com/kamimxr/p/11545032.html

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326445347&siteId=291194637