codevs 1183 泥泞的道路 图论,spfa判环,二分答案

来源:互联网 发布:导航升级软件下载 编辑:程序博客网 时间:2024/05/18 02:07

codevs 1183 泥泞的道路
题目大意:有N个城市,任意两城市间有道路连接,求从1号城市到N号城市总路程/总时间最大的路线
思路:二分答案,将总路程/总时间的比值进行二分,设为ans。以 w = s – t * ans;建边,跑最长路。如果有正环就继续,没有正环,就停止。

#include <iostream>#include <cstdio>#include <cstring>#include <queue>using namespace std;int s[105][105],t[105][105],n,vis[105],cnt[105];double g[105][105],dis[105],r = 10000,l = 0,mid;queue <int> q;bool spfa(double ans){    memset(vis,0,sizeof(vis));    memset(cnt,0,sizeof(cnt));    for(int i = 1 ; i <= n; ++i)        for(int j = 1; j <= n; ++j)            g[i][j] = s[i][j] - t[i][j] * ans;      while(!q.empty()) q.pop();    for(int i = 1; i <= n; ++i) dis[i] = -99999999.0;       q.push(1);    dis[1] = 0;    vis[1] = 1;    while(!q.empty())    {        int u = q.front();        q.pop();        vis[u] = 0;        for(int i = 1; i <= n; ++i)            if(dis[i] < dis[u] + g[u][i])            {                dis[i] = dis[u] + g[u][i];                if(!vis[i])                {                    vis[i] = 1;                    ++cnt[i];                     if(cnt[i] > n)  return 1;                                   q.push(i);                }                           }    }    if(dis[n] > 0) return 1;    return 0;   }int main(){    scanf("%d",&n);    for(int i = 1; i <= n; ++i)    for(int j = 1; j <= n; ++j)     {        scanf("%d",&s[i][j]);    }    for(int i = 1; i <= n; ++i)    for(int j = 1; j <= n; ++j)     {        scanf("%d",&t[i][j]);    }    while(r - l > 0.0001)    {        mid = (l + r) / 2.0;        spfa(mid);        if(spfa(mid)) l = mid;        else r = mid;           }    printf("%.3lf",mid);        return 0;}
阅读全文
0 0