1447. Portkey Network

http://acm.timus.ru/problem.aspx?space=1&num=1447

最优比率生成树(最小生成树+二分)

黑书 p303

代码:

#include<iostream>

#include<cstdio>

#include<cstring>

#include<string>

#include<map>

#include<vector>

#include<stack>

#include<set>

#include<map>

#include<queue>

#include<deque>

#include<algorithm>

#include<cmath>

#define LL long long

//#pragma comment(linker, "/STACK:1024000000,1024000000")

using namespace std;

const double eps=1e-9;

const int INF=0x3f3f3f3f;

const double FINF=1e12;

const int N=1005;

const int M=500005;

/*

int f[N];

struct node

{

    int l,r,t,c;

    double tmp;

}edge[M];

int x[M];

int fx(int x)

{

    if(f[x]!=x)

    f[x]=fx(f[x]);

    return f[x];

}

bool cmp(node x,node y)

{

    return x.tmp<y.tmp;

}

double kruskal(int n,int m,double k)

{

    for(int i=1;i<=n;++i)

    f[i]=i;

    for(int i=0;i<m;++i)

    edge[i].tmp=edge[i].c-k*edge[i].t;

    sort(edge,edge+m,cmp);

    for(int i=0;i<m;++i)

    {

        if(fx(edge[i].l)==fx(edge[i].r))

        {x[i]=0;}

        else

        {x[i]=1;f[fx(edge[i].l)]=fx(edge[i].r);}

    }

    double sum=0.0;

    for(int i=0;i<m;++i)

    {

        sum+=(edge[i].c-k*edge[i].t)*x[i];

    }

    return sum;

}

*/

int c[N][N],t[N][N],f[N];

double tmp[N][N],dist[N];

bool had[N];

double prim(int n,double k)

{

    for(int i=1;i<=n;++i)

    for(int j=1;j<=n;++j)

    if(c[i][j]!=-1)

    tmp[i][j]=c[i][j]-k*t[i][j];

    for(int i=1;i<=n;++i)

    dist[i]=FINF;

    dist[1]=0.0;

    memset(had,false,sizeof(had));

    for(int w=0;w<n;++w)

    {

        int l=-1;

        for(int i=1;i<=n;++i)

        if(!had[i]&&(l==-1||dist[i]<dist[l]))

        l=i;

        had[l]=true;

        for(int i=1;i<=n;++i)

        if(!had[i]&&c[l][i]!=-1&&dist[i]>tmp[l][i])

        {dist[i]=tmp[l][i];f[i]=l;}

    }

    double sum=0.0;

    for(int i=2;i<=n;++i)

    sum+=tmp[f[i]][i];

    return sum;

}

int main()

{

    //freopen("data.in","r",stdin);

    int n,m;

    while(scanf("%d %d",&n,&m)!=EOF)

    {

        memset(c,-1,sizeof(c));

        while(m--)

        {

            int i,j,t1,c1;

            scanf("%d %d %d %d",&i,&j,&t1,&c1);

            t[i][j]=t[j][i]=t1;

            c[i][j]=c[j][i]=c1;

        }

        double l=0.0,r=1e6;

        double mid;

        while(r-l>=eps)

        {

            mid=(l+r)/2.0;

            if(prim(n,mid)<=0.0)

            r=mid;

            else

            l=mid;

        }

        printf("%.8lf\n",mid);

    }

    return 0;

}

  

 

你可能感兴趣的:(NetWork)