P1113 Tâches (tri topologique ou retour en arrière mémoire)

description du sujet

JohnLa ferme a beaucoup de tâches à accomplir avant de traire les vaches et chaque tâche prend un certain temps pour être accomplie. Par exemple : ils doivent rassembler les vaches, les conduire dans l'étable, nettoyer les mamelles des vaches et quelques autres travaux. Il est essentiel d'effectuer toutes les tâches le plus tôt possible afin d'avoir plus de temps pour exprimer davantage de lait. Bien entendu, certaines tâches ne peuvent être effectuées tant que d’autres ne sont pas terminées. Par exemple : vous ne pouvez commencer à nettoyer le pis de la vache qu'après l'avoir conduite dans l'étable, et vous ne pouvez pas traire la vache avant de nettoyer le pis. Nous appelons ces tâches les préparations à la réalisation de ce travail. Il existe au moins une tâche qui ne nécessite pas de travail de préparation et la tâche qui peut être démarrée au plus tôt est marquée comme Tâche 1. JohnIl existe une liste de n tâches à accomplir, et cette liste a un certain ordre. La préparation des tâches k (k>1) n'est possible que dans les tâches 1 à k−1.

Écrivez un programme qui lit les descriptions de poste pour chaque tâche de 1 à n. Calculez le temps minimum pour que toutes les tâches soient accomplies. Bien sûr, des tâches indépendantes peuvent être effectuées en même temps, et vous pouvez supposer que Johnla ferme dispose de suffisamment de travailleurs pour effectuer un certain nombre de tâches en même temps.

format d'entrée

Ligne 1 : un entier n, le nombre de tâches à effectuer (3≤n≤10 000) ;

Lignes 2 à (n+1) : Il y a n lignes au total, et chaque ligne comporte des entiers séparés par 1 espace, qui représentent respectivement :

* Numéro de séquence du travail (1 à n, classé dans le fichier d'entrée) ;

* Le temps nécessaire pour terminer les travaux (1≤len≤100) ;

* Quelques travaux préparatoires à réaliser, le nombre total ne dépasse pas 100, et se termine par un chiffre 0. Certaines tâches ne nécessitent pas de travail préparatoire et ne décrivent qu'un seul 0, et aucun espace supplémentaire n'apparaîtra dans l'ensemble du fichier d'entrée.

format de sortie

Un nombre entier représentant le temps minimum requis pour effectuer toutes les tâches.

Exemples d'entrée et de sortie

Tapez #1 pour copier

7 
1 5 0 
2 2 1 0 
3 3 2 0 
4 6 1 0 
5 1 2 4 0 
6 8 2 4 0 
7 4 3 5 6 0

copie de la sortie n°1

23

Signification du titre :

Vous devez effectuer les tâches précédentes avant de passer à l'étape suivante, et les tâches peuvent être effectuées en même temps. Nous utilisons gourmand pour trouver la tâche la plus importante à accomplir en même temps.

Analyser :

Solution 1 :

En utilisant l'algorithme de retour en arrière de la mémoire dfs, lorsque le dernier point est atteint, ce doit être la tâche que vous souhaitez et l'heure doit être ajoutée.

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
const int N = 10010;
int f[N];
int time1[N];
vector<int> a[N];
int dfs(int x) {
	if (f[x]) return f[x];//该节点已经遍历过了,减枝
	for (int i = 0; i < a[x].size(); i++) {
		f[x] = max(f[x], dfs(a[x][i])); //说有子集中最大的节点
	}
	f[x] += time1[x]; // 加上自己需要的时间
	return f[x];
}
int main() {
	
	int n;
	cin >> n;
	for (int i = 0; i < n; i++) {
		int x, y,z;
		cin >> x >> y >> z;
		time1[x] = y;
		while(z != 0){
			a[z].push_back(x);// 只有完成z 后才能完成 x 所以有z -> x的边
			scanf("%d", &z);
		}
	}

	int ans = 0;
	for (int i = 1; i <= n; i++) {
		ans = max(ans, dfs(i));
	}
	cout << ans<<endl;
	return 0;
}

Solution 2 :

Utilisez les enregistrements de file d'attente, le tri topologique et les points de poussée avec un degré d'entrée de 0 dans la file d'attente.

#include<iostream>
#include<vector>
#include<algorithm>
#include<queue>
using namespace std;
const int N = 10010;
int f[N];
int time1[N];
vector<int> a[N];
int in[N];
int main() {
	queue<int> q;
	int n;
	cin >> n;
	for (int i = 0; i < n; i++) {
		int x, y,z;
		cin >> x >> y >> z;
		time1[x] = y;
		while(z != 0){
			a[z].push_back(x);// 只有完成z 后才能完成 x 所以有z -> x的边
			scanf("%d", &z);
			in[x]++;
		}
	}

	int ans = 0;
	for (int i = 1; i <= n; i++) {
		if (in[i] == 0) {
			q.push(i);
			f[i] = time1[i];//记录需要的时间
		}
	}

	while (!q.empty()) {
		int pro = q.front();
		q.pop();
		for (int i = 0; i < a[pro].size(); i++) {
			int u = a[pro][i];
			in[u]--;
			if (in[u] == 0) q.push(u); //入度为0
			f[u] = max(f[u], f[pro]+time1[u]);//到达这个点中最大的时间
		}
	}
	for (int i = 1; i<= n; i++) {
		ans = max(ans, f[i]);
	}
	cout << ans<<endl;
	return 0;
}

Je suppose que tu aimes

Origine blog.csdn.net/zhi6fui/article/details/129633336
conseillé
Classement