01 scores planning, SPFA - POJ3621

Topic Link

Title meaning

There is a directed graph, each point a little right, each side also has the edge right

There are cows and from any point of view, after at least two points back to square one, that is, a walking ring

After asking the right point of sigma / sigma edge weight is the largest number

Topic analysis

Initially thought out, read online say forfeit ring with SPFA also do not quite understand

Because it is not right to say that the point of each point only get it once, SPFA is how to deal with this point?

Then I think, because I was thinking the exclusion of backtrack

Because backtrack did not get right to the point, but increased the edge weight is definitely not worth

But SPFA sentence negative loop will not backtrack ah! ! ! If you return the same way, that it still rings that overlap the edge of it

So I worry about

——————————————————————

If sigmaPi / sigmaWi maximize, so any one answer ans must <= sigmaPi / sigmaWi

What is the conversion sigmaPi-sigmaWi * ans> = 0 => sigma (Pi-ans * Wi)> = 0

Then is two points if ans satisfy this equation, low = mid, or high = mid

But the sigma (Pi-ans * Wi) how demand it

Only think with SPFA, if it shows negative loop sigma edge Quanshi back to this starting point from a starting point to walk around <0

So the right side into our Pi-ans * Wi can do

Topic Code

Handwriting can be initialized too, memset will wa, do not know why ......

Metaphysics memset

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
using namespace std;
typedef long long LL;
const int maxm=5007;
const int maxn=1007;
const double eps=1e-7;
struct edge{
    int to,next,dis;
}e[maxm];
int head[maxm],tot;
void add(int u,int v,int w){
    e[tot].dis=w;
    e[tot].to=v;
    e[tot].next=head[u];
    head[u]=tot++;
}
int f[maxn],n,m,a,b,c;
bool SPFA(double x){
    double dis[maxn];
    bool vis[maxn];
    int num[maxn];
    for(int i=1;i<=n;i++){
        dis[i]=1e100;
        vis[i]=false;
        num[i]=0;
    }
//    memset(dis,1e100,sizeof(dis));
//    memset(vis,false,sizeof(vis));
//    memset(num,0,sizeof(num));
    queue<int>q;
    q.push(1);
    dis[1]=0;
    vis[1]=true;
    num[1]++;
    while(!q.empty()){
        int u=q.front();q.pop();
        vis[u]=false;
        for(int i=head[u];i!=-1;i=e[i].next){
            int v=e[i].to;
            if(dis[v]>dis[u]+x*e[i].dis-f[v]){
                dis[v]=dis[u]+x*e[i].dis-f[v];
                if(!vis[v]){
                    vis[v]=true;
                    q.push(v);
                    num[v]++;
                    if(num[v]>n)return true;
                }
            }
        }
    }
    return false;
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        scanf("%d",&f[i]);
    memset(head,-1,sizeof(head));
    for(int i=1;i<=m;i++){
        scanf("%d%d%d",&a,&b,&c);
        add(a,b,c);
    }
    double l=0.0,r=10000,mid;
    while(r-l>eps){
        mid=(l+r)/2;
        if(SPFA(mid))l=mid;
        else r=mid;
    }
    printf("%.2f\n",mid);
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/helman/p/11332178.html