题目链接
Sightseeing Cows
题解
0-1分数规划
代码
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<queue>
using namespace std;
const int V=1000+5;
const int E=5000+5;
int pnt[E],nxt[E];
int e,head[V],n,m;
double d[V],w[E];
bool vis[V];
int cnt[V];
double val[V];
const int INF=0x3f3f3f3f;
const double eps=1e-3;
inline int get_int()
{
int x=0,f=1;
char c;
for(c=getchar();(!isdigit(c))&&(c!='-');c=getchar());
if(c=='-') f=-1,c=getchar();
for(;isdigit(c);c=getchar()) x=(x<<3)+(x<<1)+c-'0';
return x*f;
}
inline void addEdge(int u,int v,int c)
{
nxt[++e]=head[u];
head[u]=e;
pnt[e]=v;
w[e]=c;
}
inline bool spfa(double mid)
{
queue<int> q;
while(!q.empty())q.pop();
memset(cnt,0,sizeof(cnt));
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;i++)d[i]=INF;
q.push(1);
d[1]=0;
vis[1]=1;
cnt[1]++;
while(!q.empty())
{
int u=q.front();
q.pop();
vis[u]=0;
for(int i=head[u];i;i=nxt[i])
{
int v=pnt[i];
if(d[v]>d[u]+w[i]*mid-val[v])
{
d[v]=d[u]+w[i]*mid-val[v];
if(!vis[v])
{
q.push(v);
vis[v]=1;
cnt[v]++;
if(cnt[v]>=n)return 0;
}
}
}
}
return 1;
}
int main()
{
n=get_int();
m=get_int();
for(int i=1;i<=n;i++)val[i]=get_int();
int a,b,c;
for(int i=0;i<m;i++)
{
a=get_int();
b=get_int();
c=get_int();
addEdge(a,b,c);
}
double ans=0,l=0,r=1000,mid;
while(r-l>=0.001)
{
mid=(l+r)/2;
if(spfa(mid))r=mid;
else {
l=mid;
ans=mid;
}
}
printf("%.2f\n",ans);
return 0;
}