zoukankan      html  css  js  c++  java
  • JZOJ 5353. 【NOIP2017提高A组模拟9.9】村通网

    题目

    为了加快社会主义现代化,建设新农村,农夫约(Farmer Jo)决定给农庄里每座建筑都连上互联网,方便未来随时随地网购农药。
    他的农庄很大,有N 座建筑,但地理位置偏僻,网络信号很差。
    一座建筑有网,当且仅当满足以下至少一个条件:

    1、给中国移动交宽带费,直接连网,花费为A。
    2、向另外一座有网的建筑,安装共享网线,花费为B×两者曼哈顿距离。

    现在,农夫约已经统计出了所有建筑的坐标。他想知道最少要多少费用才能达到目的。

    分析

    最小生成树
    因为我们不确定根,所以可以考虑让 (0) 连向每个点,边权 (A)

    (Code)

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    using namespace std;
    
    const int N = 1005;
    int n , A , B , X[N] , Y[N] , dis[N] , vis[N] , e[N][N];
    
    void Prim()
    {
    	for(register int i = 0; i <= n + 1; i++) dis[i] = 1e9 , vis[i] = 0;
    	int k , ans = 0;
    	dis[0] = 0;
    	for(register int i = 1; i <= n + 1; i++)
    	{
    		k = n + 1;
    		for(register int j = 0; j <= n; j++)
    			if (!vis[j] && dis[j] < dis[k]) k = j;
    		vis[k] = 1 , ans += dis[k];
    		for(register int j = 0; j <= n; j++)
    			if (!vis[j] && dis[j] > e[k][j]) dis[j] = e[k][j];
    	}
    	printf("%d
    " , ans);
    }
    
    int main()
    {
    	freopen("pupil.in" , "r" , stdin);
    	freopen("pupil.out" , "w" , stdout);
    	scanf("%d%d%d" , &n , &A , &B);
    	for(register int i = 1; i <= n; i++) scanf("%d%d" , &X[i] , &Y[i]);
    	memset(e , 0x3f3f3f3f , sizeof e);
    	for(register int i = 1; i <= n; i++)
    		for(register int j = i + 1; j <= n; j++)
    			e[i][j] = e[j][i] = (abs(X[i] - X[j]) + abs(Y[i] - Y[j])) * B;
    	for(register int i = 1; i <= n; i++) e[0][i] = e[i][0] = A;
    	Prim();
    }
    
  • 相关阅读:
    2019-9-2-C#枚举中使用Flags特性
    2019-9-2-C#枚举中使用Flags特性
    2019-8-31-C#-转换类型和字符串
    2019-8-31-C#-转换类型和字符串
    2019-8-31-C#-获取进程退出代码
    2019-8-31-C#-获取进程退出代码
    access truncate
    GIT分布式版本控制系统
    iSCSI的配置(target/initiator)
    chkconfig命令
  • 原文地址:https://www.cnblogs.com/leiyuanze/p/13830925.html
Copyright © 2011-2022 走看看