"Algorithm Note" learning diary-6.6 priority_queue common usage in detail

6.6 Common usage of priority_queue

Codeup Contest ID:100000601

Question A: Task scheduling

Title Description
Read a task scheduling sequence and output a scheduling method suitable for n tasks.
Input The
input contains multiple sets of test data.
Enter an integer n (n <100000) in the first line of each group, indicating that there are n tasks.
In the next n lines, the first in each line indicates the pre-order task. The tasks in parentheses are several post-order tasks, which means that the post-order task can only start when the pre-order task is completed. If the postorder is NULL, there is no successor task.
Output
Output scheduling method. If there are multiple suitable scheduling methods, please output the one with the smallest lexicographic order.
Sample input

4
Task0(Task1,Task2)
Task1(Task3)
Task2(NULL)
Task3(NULL)

Sample output

Task0 Task1 Task2 Task3

Thinking
this problem is clearly a priority queue, in order to facilitate the calculation here, I built a structure, which contains the name of the task and priority, and to make large value smaller priority, the priority is initialized to zero, so every time When calculating subsequent tasks, just add 1 to the priority of subsequent tasks.

My idea is to first create a map of string mapping to int , read and process all the information of the topic, here we should pay attention to, when calculating the priority of the post-order task, you cannot simply m [taskname] ++ In other words, if it is simple to add, task3 is an element that has never appeared, then the priority of task3 will also be 1, the same as task1 and task2).

Because there is a link between the priority of the pre-order task and the post-order task, the calculation of the priority of our post-order task should be based on the priority of the pre-order task, plus 1 to complete the pre-order Relationship building.

Finally, just use the iterator to traverse the entire map, save the key and value values ​​into the structure, and then put the current structure into the queue. After all the information of the map is processed, the queue at this time is the result we want, so we can simply traverse the queue output.

In addition, the priority judgment structure cmp of the queue cannot simply write the relationship of the priority value size, because the title says that the one with the smallest lexicographic order should be output, therefore,When the priorities are equal, the lexicographic order should be set to high priority. Look at the code specifically ~
code

#include<cstdio>
#include<string.h>
#include<algorithm>
#include<queue>
#include<map>
#include<string>
#include<iostream>
using namespace std;
struct task{
	string TaskName;
	int yxj;//优先级,这里规定小的数为高优先级
	task(){
		TaskName.clear();
		yxj = 0;
	}
};
struct cmp{
	bool operator () (task a, task b){
		if(a.yxj!=b.yxj) return a.yxj>b.yxj;//如果优先级不相等,则小的优先级大 
		else return a.TaskName>b.TaskName;//如果优先级相等,则字母序小的优先级大 
	}
};
map<string, int> m;
priority_queue<task, vector<task>, cmp> q;
int main(){
	int n;
	while(cin>>n){
		for(int i=0;i<n;i++){
			string temp, temptask;
			cin>>temp;
			int left = temp.find("(");
			int right = temp.find(")");
			if(i==0) m[temp.substr(0, left)] = 0;
			for(int i=left+1;i<=right;i++){
				if(temp[i]==','||i==right){
					if(temptask=="NULL") break;
					m[temptask] = m[temp.substr(0, left)]+1;//优先级比前一级低一级 
					temptask.clear();
					continue;
				}
				temptask += temp[i];
			}
		}
		for(map<string, int>::iterator it=m.begin();it!=m.end();it++){
			task tmp;
			tmp.TaskName = it->first;
			tmp.yxj = it->second;
			q.push(tmp);
		}
		for(int i=0;i<n;i++){
			if(i==0){
				cout<<q.top().TaskName;
				q.pop();
			}
			else{
				cout<<" "<<q.top().TaskName;
				q.pop();	
			}
		}
		cout<<endl;
		m.clear();//清空map,注意队列没有clear函数,而且不需要手动清空,pop的时候已经清空了 
	}
	return 0;
}

summary

After finishing this big question, the feeling is similar to that of map, but because map is automatically sorted by the value of key from small to large, and here the key is a string, what we want in this question is value. The values ​​are sorted from small to large, so you can actually use unordered_map, and then put each key and value in this map as a pair, put it into the vector, and finally just write a sort function to sort the vector. Can meet the requirements of this question, but if you can remember the writing of the priority queue sorting rules (using a structure or friend function ), it is more convenient to prefer the queue.

Published 54 original articles · won 27 · views 4985

Guess you like

Origin blog.csdn.net/weixin_42257812/article/details/105329288