洛谷 P2746 [USACO5.3]校园网

本文探讨了在一个由学校构成的有向图中,如何优化软件分发策略。提出了两个主要任务:一是确定最少的软件投放学校数量,使所有学校都能获得软件;二是计算额外需要的有向边数,确保任一学校的软件投放能让所有学校受益。文章深入分析了强连通分量的概念,介绍了通过缩点到有向无环图(DAG)来简化问题的方法,并提供了详细的算法实现。

题面

学校间构成一个有向图,当这个学校得到软件时,它会拷贝给所有的目标
任务A:为了让所有学校都可用上软件,最少需要给几个学校投放软件
任务B:为了让给任意一个学校投放软件,其他学校都可以得到软件,需要新增多少条有向边
学校数<=100

分析

首先用强连通分量缩点到DAG情况
特殊情况:整个图是一个强连通分量,那么任务A=1,任务B=0

普遍情况
考虑任务A,对于任何一个入度0的点(包括缩点形成的点),都必须得有投放安排(否则不可能从别的地方将软件给他拷贝),这就是任务A的结果

任务B:
相当于把DAG通过加边再变成强连通分量,策略是通过连接出度0的点和入度0的点,使得所有出度0点和入度0的点消失,连接并非随意,而是有策略(在这个题没有体现,只求数量),这里只是说明存在这一情况,并非只是简单消灭出入度0的点即可。

蓝色虚线是新增边,黑色线是原本存在的。
不难发现,消灭入度0需要A答案那么多边,消灭出度0需要出度0的点的数量那么多边。
综合一下,取max即可

代码

#include "cstdlib"
#include <iostream>
#include<algorithm>
#include<vector>
#include<stack>
using namespace std;
vector<int> G[10004];
int dfs_clock = 0, scc_cnt = 0;//时间戳,强连通分量组编号
int sccno[104];//表示每个点属于哪个强连通块
int pre[104];//dfs序
int low[104];//low[u]表示u及其后带通过反向边最多能返回到哪
stack<int> s;//存当前的节点
int in[104];//每一组强连通分量的入度统计
int out[104];//每一组出度统计
void dfs(int u)
{
	pre[u] = low[u] = ++dfs_clock;
	s.push(u);
	for (int i = 0; i < G[u].size(); i++)
	{
		int v = G[u][i];//下一个
		if (!pre[v])//未到过v
		{
			dfs(v);
			low[u] = min(low[u], low[v]);
		}
		else if (!sccno[v])//有可能是新的反向边
		{
			low[u] = min(low[u], pre[v]);
		}
	}
	if (low[u] == pre[u])//是第一次发现这个连通分量的点
	{
		scc_cnt++;
		while (true)
		{
			int x = s.top();s.pop();
			sccno[x] = scc_cnt;
			if (x == u)break;
		}
	}
}
void find_scc(int n)
{
	for (int i = 1; i <= n; i++)
	{
		if (!pre[i])dfs(i);
	}
}
int main()
{
	ios::sync_with_stdio(false);
	int n, u, v;
	cin >> n;
	for (int i = 1; i <= n; i++)
	{
		while (true)
		{
			cin >> v;
			if (v == 0)break;
			G[i].push_back(v);
		}
	}
	find_scc(n);//开始寻找强连通分量的函数

	//sccno已经处理完,1~scc_cnt

	//开始处理每个块的入度问题(A任务),0入度必须安排
	for (int i = 1; i <= n; i++)
	{
		for (int j = 0;j < G[i].size();j++)//(i,G[i][j])是一条边
		{
			if (sccno[i] != sccno[G[i][j]])in[sccno[G[i][j]]]++,out[sccno[i]]++;//不是同一个块,则G[i][j]所属连通块的入度++
		}
	}
	int totin = 0,totout=0;//此时记录in为0的块的个数
	for (int i = 1; i <= scc_cnt; i++)
	{
		if (in[i] == 0)totin++;
		if (out[i] == 0)totout++;
	}
	cout << totin<<endl;
	if (scc_cnt > 1)cout << max(totin, totout);
	else cout << 0;

	return 0;
}

内容概要:本文介绍了ENVI Deep Learning V1.0的操作教程,重点讲解了如何利用ENVI软件进行深度学习模型的训练与应用,以实现遥感图像中特定目标(如集装箱)的自动提取。教程涵盖了从数据准备、标签图像创建、模型初始化与训练,到执行分类及结果优化的完整流程,并介绍了精度评价与通过ENVI Modeler实现一键化建模的方法。系统基于TensorFlow框架,采用ENVINet5(U-Net变体)架构,支持通过点、线、面ROI或分类图生成标签数据,适用于多/高光谱影像的单一类别特征提取。; 适合人群:具备遥感图像处理基础,熟悉ENVI软件操作,从事地理信息、测绘、环境监测等相关领域的技术人员或研究人员,尤其是希望将深度学习技术应用于遥感目标识别的初学者与实践者。; 使用场景及目标:①在遥感影像中自动识别和提取特定地物目标(如车辆、建筑、道路、集装箱等);②掌握ENVI环境下深度学习模型的训练流程与关键参数设置(如Patch Size、Epochs、Class Weight等);③通过模型调优与结果反馈提升分类精度,实现高效自动化信息提取。; 阅读建议:建议结合实际遥感项目边学边练,重点关注标签数据制作、模型参数配置与结果后处理环节,充分利用ENVI Modeler进行自动化建模与参数优化,同时注意软硬件环境(特别是NVIDIA GPU)的配置要求以保障训练效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值