day21

时间:2019-08-21
本文章向大家介绍day21,主要包括day21使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

好难,得分40/400;

加个0不就满分了吗

T1写了个最小生成树,但没有考虑完全;

题意:从N个点中取M个点生成一棵最小生成树,使他的边权与点权的比值最小;

由于N及其小,可以枚举取哪些点来做一棵最小生成树;

为了避免精度问题,可以考虑去分母变成乘法

代码

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cctype>
#include<cstring>
#define oyy main
using namespace std;
inline int read()
{
    int x=0,f=1;char c=getchar();
    while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
    while(isdigit(c)){x=(x<<3)+(x<<1)+(c^48);c=getchar();}
    return x*f;
}
int w[20],m,n;
int mp[20][20];
int ans[20],v[20],temp[20],ans1=1,ans2=1,bq,dq;
void prime()
{
    int d[20]={},vv[20]={};
    memset(d,0x3f,sizeof(d));
    d[temp[1]]=0;
    for(int i=1;i<=m;i++)
    {
        int k=0,minn=0x7ffff;
        for(int j=1;j<=m;j++)
        if(!vv[temp[j]]&&minn>d[temp[j]])
        {
            minn=d[temp[j]];k=temp[j];
        }
        vv[k]=1;
        for(int j=1;j<=m;j++)
        if(!vv[temp[j]]&&d[temp[j]]>mp[k][temp[j]])d[temp[j]]=mp[k][temp[j]];
    }
    for(int i=1;i<=m;i++)
    {
        bq+=d[temp[i]];
        dq+=w[temp[i]];
    }
    if(bq*ans2<dq*ans1)
    {
        for(int i=1;i<=m;i++)
        ans[i]=temp[i];
        ans1=bq;
        ans2=dq;
    }
    return;
}
void dfs(int x,int i)
{
    if(x==m)
    {
        bq=0;dq=0;
        prime();
        return;
    }
    i++;
    for(;i<=n;i++)
        if(!v[i])
        {
            x++;
            temp[x]=i;
            v[i]=1;
            dfs(x,i);
            temp[x]=0;
            v[i]=0;
            x--;
        }
}
inline int cmp(int x,int y){return x<y;}
int oyy()
{
    freopen("ratio.in","r",stdin);freopen("ratio.out","w",stdout);
    n=read();m=read();
    for(int i=1;i<=n;i++)
    w[i]=read();
    for(int i=1;i<=n;i++)
    for(int j=1;j<=n;j++){
    mp[i][j]=read();if(i==j)mp[i][j]=0x7ffff;}
    dfs(0,0);
    sort(ans+1,ans+m+1,cmp);
    for(int i=1;i<=m;i++)
    cout<<ans[i]<<" ";
    return 0;
}
View Code

原文地址:https://www.cnblogs.com/Frost-Delay/p/day21.html