#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<ctime>
using namespace std;
#define N 110
#define M 10010
#define inf 0x3f3f3f3f
#define eps 1e-4
int n;
int s[N][N],t[N][N];
int cnt=-1,head[N],vis[N],tim[N];
double dis[N];
struct Edge
{
    int to,nxt;
    double w;
} e[M];
void adde(int u,int v,double w)
{
    e[++cnt].w=w;
    e[cnt].to=v;
    e[cnt].nxt=head[u];
    head[u]=cnt;
}
bool SPFA(int s)
{
    memset(tim,0,sizeof(tim));
    memset(vis,0,sizeof(vis));
    memset(dis,-inf,sizeof(dis));
    deque <int> q;
    dis[s]=0,vis[s]=1;
    q.push_back(s);
    while(!q.empty())
    {
        int now=q.front();
        q.pop_front();
        vis[now]=0;
        for(int i=head[now]; ~i; i=e[i].nxt)
        {
            int v=e[i].to;
            if(dis[v]<dis[now]+e[i].w)
            {
                dis[v]=dis[now]+e[i].w;
                if(!vis[v])
                {
                    vis[v]=1;
                    tim[v]++;
                    if(tim[v]>n)//这是个环,那么我们之一直走下去就一定能走出一条最长路。
                        return 1;//所以退出去吧
                    q.push_back(v);
                }
            }
        }
    }
    if(dis[n]>0)
        return 1;
    return 0;
}
bool Check(double mid)
{
    cnt=-1;
    memset(head,-1,sizeof(head));
    for(int i=1; i<=n; ++i)
        for(int j=1; j<=n; ++j)
        {
            double w=1.0*s[i][j]-mid*t[i][j];//1.0为了把它double化
            adde(i,j,w);
        }
    if(SPFA(1))
        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]);
    double l=0,r=10000,ans;
    while(r-l>eps)//浮点数二分
    {
        double mid=(l+r)/2.0;
        if(Check(mid))
            l=mid;
        else
            r=mid;
    }
    printf("%.3f\n",l);
    return 0;
}

 

0 0 votes
文章评分

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据

0 评论
Inline Feedbacks
View all comments