#include<stdio.h>
#include<math.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const int maxn=1005;
int n,m;
double a[maxn],b[maxn];
double t[maxn];
double solve(double x)
{
for(int i=0;i<n;i++)
t[i]=a[i]-b[i]*x;
sort(t,t+n);
double ans=0;
for(int i=m;i<n;i++)
{
ans+=t[i];
}
return ans;
}
int main()
{
while(~scanf("%d%d",&n,&m),(n+m))
{
double minn=inf,maxx=-inf;
for(int i=0; i<n; i++)
{
scanf("%lf",&a[i]);
maxx=max(maxx,a[i]);
}
for(int i=0; i<n; i++)
{
scanf("%lf",&b[i]);
minn=min(minn,b[i]);
}
double l=0,r=maxx/minn;
int gg=100;
while(gg--)
{
double mid=(l+r)/2;
double k=solve(mid);
if(k>=0)
l=mid;
else
r=mid;
}
printf("%.0lf\n",100.0*l);
}
return 0;
}
最小比率生成树 poj2728
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
const int inf=0x3f3f3f3f;
const int maxn=1005;
int X[maxn],Y[maxn],W[maxn];
double a[maxn][maxn];
double b[maxn][maxn];
int n;
double solve(int x1,int y1,int x2,int y2)
{
double team=(x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);
return sqrt(team);
}
double d[maxn];
int vis[maxn];
double prime(double x)
{
for(int i=0;i<n;i++)
d[i]=a[0][i]-b[0][i]*x;
d[0]=0;
memset(vis,0,sizeof(vis)); vis[0]=1;
double ans=0;
for(int i=2;i<=n;i++)
{
double minn=inf;
int index;
for(int j=0;j<n;j++)
{
if(!vis[j]&&d[j]<minn)
{
minn=d[j];
index=j;
}
}
vis[index]=1;
ans+=minn;
for(int j=0;j<n;j++)
{
if(!vis[j]&&d[j]>a[index][j]-b[index][j]*x)
{
d[j]=a[index][j]-b[index][j]*x;
}
}
}
return ans;
}
int main()
{
while(~scanf("%d",&n)&&n)
{
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
for(int i=0;i<n;i++)
{
scanf("%d%d%d",&X[i],&Y[i],&W[i]);
for(int j=0;j<i;j++)
{
a[i][j]=a[j][i]=abs(W[i]-W[j]);
b[i][j]=b[j][i]=solve(X[i],Y[i],X[j],Y[j]);
}
}
double l=0,r=100000.0;
while(r-l>1e-5)
{
double mid=(l+r)/2;
double k=prime(mid);
if(k>=0)
l=mid;
else
r=mid;
}
printf("%.3lf\n",r);
}
}
最小比率环 poj3621
#include<stdio.h>
#include<string.h>
#include<queue>
#include<iostream>
#include<algorithm>
using namespace std;
const int inf=0x3f3f3f3f;
const int maxn=5000+10;
int n,m;
struct node
{
int u,v,nex;
double w;
}e[maxn];
int first[maxn];
double a[maxn];
int tot;
void init()
{
tot=0;
memset(first,-1,sizeof(first));
}
void edge(int u,int v,double w)
{
e[tot].v=v;
e[tot].w=w;
e[tot].nex=first[u];
first[u]=tot++;
}
int vis[maxn];
double dis[maxn];
int pan[maxn];
int spfa(double x)
{
memset(vis,0,sizeof(vis));
for(int i=0;i<=n;i++)
dis[i]=inf*1.0;
memset(pan,0,sizeof(pan));
pan[1]++;
vis[1]=1;
queue<int>q;
dis[1]=0;
q.push(1);
while(!q.empty())
{
int p=q.front();
q.pop();
vis[p]=0;
for(int i=first[p];~i;i=e[i].nex)
{
int v=e[i].v;
if(dis[v]>dis[p]+e[i].w*x-a[v])
{
dis[v]=dis[p]+e[i].w*x-a[v];
if(!vis[v])
{
vis[v]=1;
q.push(v);
pan[v]++;
if(pan[v]>n)//判断负权边
return 1;
}
}
}
}
return 0;
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
init();
for(int i=1;i<=n;i++)
scanf("%lf",&a[i]);
for(int i=0;i<m;i++)
{
int u,v;
double w;
scanf("%d%d%lf",&u,&v,&w);
edge(u,v,w);
}
double l=0,r=1000.0;
while(r-l>1e-3)
{
double mid=(l+r)/2;
if(spfa(mid))
l=mid;
else
r=mid;
}
printf("%.2lf\n",l);
}
return 0;
}