您的位置:首页 > 其它

POJ 3621-Sightseeing Cows-最优比率环|SPFA+二分

2016-03-06 16:47 471 查看
最优比率环问题。二分答案,对于每一个mid,把节点的happy值归类到边上。

对于每条边,用mid×weight减去happy值,如果不存在负环,说明还可以更大。

/*--------------------------------------------------------------------------------------*/
//        Helica's header
//        Second Edition
//        2015.11.7
//
#include <algorithm>
#include <iostream>
#include <cstring>
#include <ctype.h>
#include <cstdlib>
#include <cstdio>
#include <vector>
#include <string>
#include <queue>
#include <stack>
#include <cmath>
#include <set>
#include <map>

//debug function for a N*M array
#define debug_map(N,M,G) printf("\n");for(int i=0;i<(N);i++)\
{for(int j=0;j<(M);j++){\
printf("%d",G[i][j]);}printf("\n");}
//debug function for int,float,double,etc.
#define debug_var(X) cout<<#X"="<<X<<endl;
/*--------------------------------------------------------------------------------------*/
using namespace std;

const int INF = 0x3f3f3f3f;
const int maxn = 1e3+100;
const double eps = 1e-3;
int N,M;
int happy[maxn];

struct Edge
{
int to,next,w;
}edge[10*maxn];

int head[maxn],cnt[maxn],tol;
double dist[maxn];
bool vis[maxn];

bool SPFA(double mid)
{
memset(vis,false,sizeof(vis));
memset(cnt,0,sizeof(cnt));
for(int i=1;i<=N;i++)dist[i]=INF;
dist[1]=0;
queue<int>Q;
Q.push(1);
while(!Q.empty()){
int u=Q.front();
Q.pop();
vis[u]=false;
cnt[u]++;
if(cnt[u]>N)return true;
for(int i=head[u];i!=-1;i=edge[i].next){
int v=edge[i].to,w=edge[i].w;
double tmp=mid*w-happy[v];
if(dist[u]+tmp<dist[v]){
dist[v]=dist[u]+tmp;
if(!vis[v]){ vis[v]=true;Q.push(v); }
}
}
}
return false;
}
void add_edge(int u,int v,int w)
{
edge[tol].to = v;
edge[tol].w = w;
edge[tol].next = head[u];
head[u] = tol++;
}

int main()
{
//freopen("input.in","r",stdin);
while(~scanf("%d%d",&N,&M))
{
memset(head,-1,sizeof head);
tol = 0;
for(int i=1;i<=N;i++)    scanf("%d",&happy[i]);
for(int i=0,u,v,w;i<M;i++)
{
scanf("%d%d%d",&u,&v,&w);
add_edge(u,v,w);
}
double L = 0,R = 10000.0,mid;

while(abs(L-R)>eps)
{
mid = (L+R)/2.0;
if(SPFA(mid)) L = mid;
else          R = mid;
}

printf("%.2f\n",mid);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: