1. 程式人生 > >2018.09.12 poj3621Sightseeing Cows(01分數規劃+spfa判環)

2018.09.12 poj3621Sightseeing Cows(01分數規劃+spfa判環)

傳送門 01分數規劃板題啊。 發現就是一個最優比率環。 這個直接二分+spfa判負環就行了。 程式碼:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define N 1005
#define M 5005
using namespace std;
int n,m,first[N],cnt=0;
bool in[N];
double l,r,dis[N],d[N];
struct Node{int v,next;double
w;}e[M<<1]; inline void add(int u,int v,double w){e[++cnt].v=v,e[cnt].next=first[u],e[cnt].w=w,first[u]=cnt;} inline bool spfa(int p,double mid){ in[p]=true; for(int i=first[p];i;i=e[i].next){ int v=e[i].v; double tmp=e[i].w*mid-d[p]; if(dis[v]>dis[p]+tmp){ if
(dis[v]=dis[p]+tmp,in[v])return true; if(spfa(v,mid))return true; } } return in[p]=false; } inline bool check(double tmp){ memset(dis,0,sizeof(dis)),memset(in,false,sizeof(in)); for(int i=1;i<=n;++i)if(spfa(i,tmp))return true; return false; } int main(){ scanf
("%d%d",&n,&m),r=1000.0,l=0.0; for(int i=1;i<=n;++i)scanf("%lf",&d[i]); for(int i=1;i<=m;++i){ int u,v; double w; scanf("%d%d%lf",&u,&v,&w),add(u,v,w); } while(r-l>1e-4){ double mid=(l+r)/2.0; if(check(mid))l=mid; else r=mid; } printf("%.2f",r); return 0; }