首页 > 其他分享 >P1113 杂务 (DAG拓扑排序--DP)

P1113 杂务 (DAG拓扑排序--DP)

时间:2023-08-26 10:11:58浏览次数:47  
标签:DAG -- 拓扑 ch int P1113 排序 include

这是一道拓扑排序的模板题


0 额.

所需的前置知识:

  • 图论相关的基本概念
  • 建图,存图
  • 图的遍历
  • 非常入门的DP

下面进入正文

1 引入

拓扑排序是一类用于处理 DAG(Directed acyclic graph),即有向无环图上的问题。

以这道题为例,我们分析拓扑排序的作用:

显然地,本题中各项工作是有一定的依赖条件的,也就是说我们在进行工作 X 之前可能需要先进行一些其他的工作。

而完成工作 X 所需的时间和所有 X 所依赖的工作完成的时间的最大值有关。(应该还好理解吧)

在这道题中,我们可以列出一个简单的 DP 转移方程:

\[f_i=max\{pre_i\}+a_i \]

其中\(f_i\)为从最开始到进行完第\(i\)项任务所需的时间,\(pre_i\)为\(i\)号结点的前驱数组,\(a_i\)为做第\(i\)件事所需的时间。
但是,我们如果直接进行dfs遍历,可能会出新一个问题:\(在我们计算f_i的时候,还存在没有计算过的pre_i,从而导致计算结果错误\)
那么,我们在计算的时候,应该确保在计算一个结点\(u\)时,所有与连向它的点都已经被计算过。

而实现这一过程就利用到了今天的主角:拓扑排序(topo sort)


锣鼓题解:记忆化搜索。?
此方法可以达到拓扑排序得目的

#include<bits/stdc++.h>
#define MAXN 10010
using namespace std;
int n,x,y,t,ans,len[MAXN],vis[MAXN];
vector<int>e[MAXN];
int miHoYo(int x){
	if(vis[x])	return vis[x];//如果被访问过,直接返回 
	for(int i=0;i<e[x].size();i++)// 循环:x每条边指向的点
		vis[x]=max(vis[x],miHoYo(e[x][i]));// 动态规划,求最大值 
	vis[x]+=len[x];//加上所需要的时间,构成动态规划公式 
	return vis[x];
}
int main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>x>>len[i];
		while(cin>>y)
			if(!y)	break;
			else e[y].push_back(x);
	}
	for(int i=1;i<=n;i++)//对于每个点进行dfs求f得最大值 
		ans=max(ans,miHoYo(i));//	取最大值 
	cout<<ans;
	return 0;
}

拓扑排序代码拷自Keith_2006

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cctype>
#include <vector>
#include <queue>

#define ll long long

using namespace std;

inline int read() {
	int x=0,f=1;
	char ch=getchar();
	while (!isdigit(ch)) {if (ch=='-') f=-1;ch=getchar();}
	while (isdigit(ch)) x=x*10+ch-'0',ch=getchar();
	return x*f;
}

const int N=500005;

int ind[N],f[N],a[N];  //ind--入度   f--答案   a--时间
vector <int> edge[N];
queue <int> q;

int main() {
	int n=read();
	for (int i=1;i<=n;i++) {
		int x=read();
		a[i]=read();
		while (int y=read()) {
			if (!y) break;
			edge[y].push_back(x);
            ind[x]++;
		}
	}
    //步骤一
	for (int i=1;i<=n;i++) {
		if (ind[i]==0) {
			q.push(i);
			f[i]=a[i];
		}
	};
	while (!q.empty()) {
		int rhs=q.front();
		q.pop();
        //步骤二
		for (int i=0;i<edge[rhs].size();i++) {
			int u=edge[rhs][i];
			ind[u]--;
			if (ind[u]==0) q.push(u);  //步骤三
			f[u]=max(f[u],f[rhs]+a[u]);
		}
	}
	int ans=0;
	for (int i=1;i<=n;i++) {
		ans=max(ans,f[i]);   //统计答案
	}
	printf("%d\n",ans);
	return 0;
}

拓扑排序详细讲述见P4017 最大食物链计数

标签:DAG,--,拓扑,ch,int,P1113,排序,include
From: https://www.cnblogs.com/tflsghh/p/17656269.html

相关文章

  • ubuntu磁盘只读
    ubuntu系统tab补全命令报错参考博客:linux临时文件创建失败,-bash:无法为立即文档创建临时文件:设备上没有空间ubuntu变成只读文件系统怎么办?不要慌,简单解决在Ubuntu下使用Tab键报错:cannotcreatetempfileforhere-document:nospaceleftondevice原因分析原因有......
  • gunicorn开机自启
    gunicorn设置开机自启参考博客:ubuntu配置gunicorn开机启动可能是史上最全面易懂的Systemd服务管理教程!(强烈建议收藏)需要开机运行项目,使用systemctl来控制gunicorn开机启动systemctl配置文件官方文档:systemd.service在/etc/systemd/system下增加文件project.servic......
  • openresty中几种重定向的差异比较(ngx.redirect、ngx.req.set_uri、ngx.exec)
    一.测试用的nginx.conf: userroot;worker_processes1;error_loglogs/error.log;events{worker_connections1024;}http{charsetutf-8;default_typeapplication/octet-stream; include/usr/local/openresty/nginx/conf/mime.typ......
  • # yyds干货盘点 # 有大佬知道Pandas这个上面的如何改别名吗?
    大家好,我是皮皮。一、前言前几天在Python青铜群【9527】问了一个pandas列名处理的问题,一起来看看吧。二、实现过程这里【袁学东】大佬给了一个答案,如下图所示:如此顺利地解决了粉丝的问题。三、总结大家好,我是皮皮。这篇文章主要盘点了一个Python递归的基础问题,文中针对该问题,给出了......
  • # yyds干货盘点 # 盘点一个dataframe读取csv文件失败的问题
    大家好,我是皮皮。一、前言前几天在Python钻石群【心田有垢生荒草】问了一个Pandas数据处理的问题,一起来看看吧。大佬们求教个方法 现在有个数据量很大的dataframe 要吐csv格式 但结果总是串行 加了encoding='utf-8'还是没解决 还有其他方法么?下图是他提供的图片:二、实现......
  • c 语言 数组(一维)做函数参数
    @TOC前言函数参数:函数参数是函数内外连接的接口,可以互通数据。一、传递一维数组函数调用时,实参是给形参初始化,所以,实参传递什么类型的数据,形参就以什么类型去接住。比如一维数组,如下:函数fun1传递a,因为数组名就是数组的首地址,所以用int*p形参。函数fun2传递&a,是一维数组......
  • 【MySQL 8.0】在组复制(MGR)的基础上创建InnoDB Cluster
    [root@node04~]#wgethttps://dev.mysql.com/get/Downloads/MySQL-Shell/mysql-shell-8.0.32-1.el7.x86_64.rpm[root@node04~]#yumlocalinstallmysql-shell-8.0.32-1.el7.x86_64.rpm-y[root@node04~]#mysqlshMySQLJS>\connectroot@node01:3306MySQL......
  • 统计分析 -- 聚类算法模型
    统计分析--聚类算法模型距离分析数据标准化欧氏距离与量纲有关,因此,有时需要对数据进行预处理,如标准化等。在MATLAB中的命令是zscore,调用格式Z=zscore(X)输入X表示N行p列的原始观测矩阵,行为个体,列为指标。输出Z为X的标准化矩阵:Z=(X–ones(N,1)*mean(X))./(ones(N,1)*......
  • flutter中initState(),实现异步操作
    在Flutter中,如果你需要在initState()中执行异步操作,可以使用async和await关键字。以下是一个示例,展示了如何在initState()中执行异步操作:@overridevoidinitState(){super.initState();fetchData();//异步操作示例}Future<void>fetchData()async{//......
  • 对账思路
    1.我方有,对方无我方成功,则冲账我方失败,则不处理我方超时,则置为失败2.对方有,我方无补记账,补流水,线下处理3.我方异常,对方成功我方失败,则更改流水状态为成功,补记账;我方超时,则更改流水状态为成功,补记账......