考试9.5

Posted xwww666666

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了考试9.5相关的知识,希望对你有一定的参考价值。

3>警察叔叔

题面真皮,复制自题解

考点:MST+树的遍历

 

题目大意:

给定一个无向有权图,

首先一个最小生成树 MST,从 MST 中选取一个度数大于 1 的点 作为根 K,

使每颗子树及该子树到根的边权之和方差最小。

输出 K 和最小方差的值。

 

由于N 比较大,所以只能通过 Kruskal 求MST,

接下来任选一个点作为根,进行一次遍历。

记录 w[i]表示以 i 点作为根的子树的边权之和。

 

然后依次枚举每一个点 i,该点的子树权值可以直接求出,

而以它父亲作为根的子树需要特殊处理。

这颗特殊子树的权值为最小生成树总权值减去该点权值 w[i]。

然后计算出方差,最后选取所有点当中最小方差的那个点即可。

时间复杂度:O(MlogM+N)

 

代码也不长,就是小数烦人

#include<cstdio>
#include<cstdlib>
#include<vector>
#include<queue>
#include<cstring>
using namespace std;
int n,m;
const int N=40003;
struct node

    int v;double w;
    bool operator < (const node & o) const 
     return w>o.w; 
    node(int vv,double ww)
     v=vv,w=ww; 
    node()
;
vector <node> g[N];

struct nd

    int u,v;double w;
    bool operator < (const nd & o) const
     return w>o.w; 
;
int f[N];
int find(int x)
 return !f[x]?x:f[x]=find(f[x]); 
void MST()

    priority_queue <nd> q;    
    scanf("%d%d",&n,&m);
    nd t;
    while(m--)
    
        scanf("%d%d%lf",&t.u ,&t.v ,&t.w );
        q.push(t); 
    
    int cnt=1;
    while(!q.empty() && cnt<n)
    
        t=q.top() ;q.pop() ;
        int fu=find(t.u ),fv=find(t.v );
        if(fu==fv) continue;
        
        f[fu]=fv,cnt++;
        g[t.u ].push_back(node(t.v ,t.w )); 
        g[t.v ].push_back(node(t.u ,t.w )); 
    

int fa[N],g_sz[N];
double son[N],gg[N];
void dfs(int nw,int pre)

    fa[nw]=pre;
    g_sz[nw]=g[nw].size() ;
    for(int i=0;i<g_sz[nw];i++)
    
        int v=g[nw][i].v ;
        if(v==pre) continue;
        dfs(v,nw);
        son[nw]+=son[v]+g[nw][i].w ;
    


int main()

    MST();
    dfs(1,0);
    double ans=-1;int pos=0;
    for(int i=1;i<=n;i++)
    
        if(g_sz[i]==1) continue;
        
        double ave=son[1]/g_sz[i];
        double check=0;
        for(int j=0;j<g_sz[i];j++)
        
            int v=g[i][j].v ;
            double t;
            if(v==fa[i])
                t=son[1]-son[i];
            else
                t=son[v]+g[i][j].w ;
            t-=ave;
            check+=t*t;
        
        if(ans==-1 || check<ans) ans=check,pos=i;
    
    printf("%d",pos);
    
    return 0;

记住这里的ans,

如果不知道什么是最大值,就不要瞎设,1e18都过不了。

不如老老实实-1

以上是关于考试9.5的主要内容,如果未能解决你的问题,请参考以下文章

9.5 考试 第一题 礼物题解

无纸化考试

salesforce考试多少分过

微软认证考试

剑桥英语五级考试介绍

杭州腾科华为HCIE考试流程