#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; }