1018 Communication System 枚举+剪枝

来源:互联网 发布:ubuntu 双系统安装 编辑:程序博客网 时间:2024/06/08 03:32
#include <stdio.h>#include <string.h>#include <algorithm>using namespace std;struct node{    int b,p,id; //带宽,价格,设备号码};node a[10001];bool cmp(node x, node y) { return x.b<y.b || (x.b==y.b && x.p<y.p) || (x.b==y.b && x.p==y.p && x.id<y.id); }int main(){    int T;    scanf("%d",&T);    while (T--)    {        bool flag=false;        int n,m=0,maxb[101]; //maxb是各个设备的最大带宽;        memset(maxb,0,sizeof(maxb));        double ans=0;        scanf("%d",&n);        for (int i=0; i!=n; i++)        {            int m1;            scanf("%d",&m1);            for (int j=0; j!=m1; j++)            {                scanf("%d%d",&a[m].b,&a[m].p);                if (a[m].b>maxb[i])                   maxb[i]=a[m].b;                a[m++].id=i;            }        }        sort(a,a+m,cmp);        for (int i=0; i<=m-1-(n-1); i++) //i到m-1-(n-1)保证后面至少有n个设备可选        {            bool vis[10001]; memset(vis,false,sizeof(vis));            double price=a[i].p;            int cnt=1;            vis[a[i].id]=true;            for (int j=i+1; j!=m; j++)            {                if (vis[a[j].id])                   continue;                if (a[i].b>maxb[a[j].id]) //当前枚举的 "所有设备带宽的最小带宽Bi" 比 "设备j的最大带宽MaxBj" 要大                {                    flag=true; break;     //说明当前bi已经越界,无需继续往后枚举                }                vis[a[j].id]=true;                price+=a[j].p;                cnt++;            }            if (flag || cnt<n)               break;            if (ans<a[i].b/price)               ans=a[i].b/price;        }        printf("%.3lf\n",ans);    }    return 0;}