P1364医院设置洛谷题解

来一发c++代码

题目链接:

P1364

依我个人来看:首先初始化,再计算任意两点间的最短路径,最终挨个计算路径并赋值最小值。

首先初始化,定义7个数值,分别记录节点数、路径dp数组、记录节点编号、左节点、右节点、最小值、对每个节点暂时存储的总和这些值,具体看注释:

int n,lu_jing[101][101],a[101],u,v,minn=0x7f7f7f7f7f,total;  //节点数、路径数组、记录节点编号、左节点、右节点、最小值、对每个节点暂时存储的总和
cin>>n; //输入节点数
    initialization();   //对要用到的初始化
    for(int i=1;i<=n;i++){  //二次初始化
        lu_jing[i][i]=0;
        cin>>a[i]>>u>>v;    //输入
        if(u>0){    //不是空节点
            lu_jing[i][u]=1;    //交换赋值
            lu_jing[u][i]=1;
        }
		if(v>0){    //不是空节点
            lu_jing[i][v]=1;     //一样交换赋值
            lu_jing[v][i]=1;
		}
    }
//初始化函数:
void initialization(){  //初始化
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            lu_jing[i][j]=100001;    //将要用到的全部设为最大值
        }
    }
}

然后计算任意两点的路径,注意要加一个判断不重复,否则会栽跟头(我就因此WA了):

for(int k=1;k<=n;k++){  //遍历求任意两点最短路径
		for(int i=1;i<=n;i++){
			if(i!=k){   //保证不重复(小心!不加会挂)
				for(int j=1;j<=n;j++){
					if(i!=j&&k!=j&&lu_jing[i][k]+lu_jing[k][j]<lu_jing[i][j]){
						lu_jing[i][j]=lu_jing[i][k]+lu_jing[k][j];    //进行计算
					}
				}
			}
		}
	}

最后求最短路径,千万记得total要初始化为0:

for(int i=1;i<=n;i++){
        total=0;    //初始化以丢弃以前的值
        for(int j=1;j<=n;j++){    //遍历结点求将医院设在此地的路径
            total+=lu_jing[i][j]*a[j];
        }
        minn=min(total,minn);   //如果total小于minn,则重新赋值,否则不变
	}

完结时,输出:

cout<<minn;

放一下完整代码:

#include<bits/stdc++.h>
using namespace std;
int n,lu_jing[101][101],a[101],u,v,minn=0x7f7f7f7f7f,total;  //节点数、dp数组、记录节点编号、左节点、右节点、最小值、对每个节点暂时存储的总和
void initialization(){  //初始化
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            lu_jing[i][j]=100001;    //将要用到的全部设为最大值
        }
    }
}
int main(){
    cin>>n; //输入节点数
    initialization();   //对要用到的初始化
    for(int i=1;i<=n;i++){  //二次初始化
        lu_jing[i][i]=0;
        cin>>a[i]>>u>>v;    //输入
        if(u>0){    //不是空节点
            lu_jing[i][u]=1;    //交换赋值
            lu_jing[u][i]=1;
        }
		if(v>0){    //不是空节点
            lu_jing[i][v]=1;     //一样交换赋值
            lu_jing[v][i]=1;
		}
    }
    for(int k=1;k<=n;k++){  //遍历求任意两点最短路径
		for(int i=1;i<=n;i++){
			if(i!=k){   //保证不重复
				for(int j=1;j<=n;j++){
					if(i!=j&&k!=j&&lu_jing[i][k]+lu_jing[k][j]<lu_jing[i][j]){
						lu_jing[i][j]=lu_jing[i][k]+lu_jing[k][j];    //进行计算
					}
				}
			}
		}
	}
	for(int i=1;i<=n;i++){
        total=0;    //初始化以丢弃以前的值
        for(int j=1;j<=n;j++){    //遍历结点求将医院设在此地的路径
            total+=lu_jing[i][j]*a[j];
        }
        minn=min(total,minn);   //如果total小于minn,则重新赋值,否则不变
	}
	cout<<minn;
    return 0;
}

这篇博客写完了,当然还有其他解法,我知道且对的只有这种了。

刚说到了对的,所以放一下AC验证:

https://www.luogu.com.cn/record/140803873

这是本蒟蒻的第三篇题解,白白~

  • 13
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值