首页 > 其他分享 >洛谷 P3243 [HNOI2015] 菜肴制作 - toposort 需自己理解翻译题面

洛谷 P3243 [HNOI2015] 菜肴制作 - toposort 需自己理解翻译题面

时间:2023-07-29 17:12:44浏览次数:45  
标签:toposort 菜肴 顺序 限制 题面 优先 洛谷 尽量 制作

P3243 [HNOI2015] 菜肴制作

题目描述

知名美食家小 A 被邀请至 ATM 大酒店,为其品评菜肴。ATM 酒店为小 A 准备了 \(n\) 道菜肴,酒店按照为菜肴预估的质量从高到低给予 \(1\) 到 \(n\) 的顺序编号,预估质量最高的菜肴编号为 \(1\)。

由于菜肴之间口味搭配的问题,某些菜肴必须在另一些菜肴之前制作,具体的,一共有 \(m\) 条形如 \(i\) 号菜肴必须先于 \(j\) 号菜肴制作的限制,我们将这样的限制简写为 \((i,j)\)。

现在,酒店希望能求出一个最优的菜肴的制作顺序,使得小 A 能尽量先吃到质量高的菜肴:

也就是说,

  1. 在满足所有限制的前提下,\(1\) 号菜肴尽量优先制作。

  2. 在满足所有限制,\(1\) 号菜肴尽量优先制作的前提下,\(2\) 号菜肴尽量优先制作。

  3. 在满足所有限制,\(1\) 号和 \(2\) 号菜肴尽量优先的前提下,\(3\) 号菜肴尽量优先制作。

  4. 在满足所有限制,\(1\) 号和 \(2\) 号和 \(3\) 号菜肴尽量优先的前提下,\(4\) 号菜肴尽量优先制作。

  5. 以此类推。

例 1:共 \(4\) 道菜肴,两条限制 \((3,1)\)、\((4,1)\),那么制作顺序是 \(3,4,1,2\)。

例 2:共 \(5\) 道菜肴,两条限制 \((5,2)\)、\((4,3)\),那么制作顺序是 \(1,5,2,4,3\)。

例 1 里,首先考虑 \(1\),因为有限制 \((3,1)\) 和 \((4,1)\),所以只有制作完 \(3\) 和 \(4\) 后才能制作 \(1\),而根据 3,\(3\) 号又应尽量比 \(4\) 号优先,所以当前可确定前三道菜的制作顺序是 \(3,4,1\);接下来考虑 \(2\),确定最终的制作顺序是 \(3,4,1,2\)。

例 \(2\) 里,首先制作 \(1\) 是不违背限制的;接下来考虑 \(2\) 时有 \((5,2)\) 的限制,所以接下来先制作 \(5\) 再制作 \(2\);接下来考虑 \(3\) 时有 \((4,3)\) 的限制,所以接下来先制作 \(4\) 再制作 \(3\),从而最终的顺序是 \(1,5,2,4,3\)。现在你需要求出这个最优的菜肴制作顺序。无解输出 Impossible!(首字母大写,其余字母小写)

输入格式

第一行是一个正整数 \(t\),表示数据组数。接下来是 \(t\) 组数据。对于每组数据:第一行两个用空格分开的正整数 \(n\) 和 \(m\),分别表示菜肴数目和制作顺序限制的条目数。接下来 \(m\) 行,每行两个正整数 \(x,y\),表示 \(x\) 号菜肴必须先于 \(y\) 号菜肴制作的限制。

输出格式

输出文件仅包含 \(t\) 行,每行 \(n\) 个整数,表示最优的菜肴制作顺序,或者 Impossible! 表示无解。

样例 #1

样例输入 #1

3
5 4
5 4
5 3
4 2
3 2
3 3
1 2
2 3
3 1
5 2
5 2
4 3

样例输出 #1

1 5 3 4 2 
Impossible! 
1 5 2 4 3

提示

【样例解释】

第二组数据同时要求菜肴 \(1\) 先于菜肴 \(2\) 制作,菜肴 \(2\) 先于菜肴 \(3\) 制作,菜肴 \(3\) 先于菜肴 \(1\) 制作,而这是无论如何也不可能满足的,从而导致无解。

【数据范围】

\(100\%\) 的数据满足 \(n,m\le 10^5\),\(1\le t\le 3\)。

\(m\) 条限制中可能存在完全相同的限制。

思路

由题可知,简单的拓扑序列并不能满足题目的要求 - 号小的菜肴优先制作
判环就不说了,最后的拓扑序列长度不够 n 就是有环。
那么我们想要得到题目的要求的序列,从前往后的思路就是让每一个菜肴的前置条件均满足后再放置当前菜肴,而且这样的放置需要时刻满足号小的菜肴尽量优先制作这一要求。那么其实这样的放置就是在反图上跑 topo,而且要找的是字典序最大的 topo 序列(可以利用最大堆来辅助操作)。
所以我们可以建立反图,利用最大堆跑 topo,最后倒序输出 topo 序列即可

代码

//>>>Qiansui
#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define mem(x,y) memset(x, y, sizeof(x))
#define debug(x) cout << #x << " = " << x << '\n'
#define debug2(x,y) cout << #x << " = " << x << " " << #y << " = "<< y << '\n'
//#define int long long

using namespace std;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<ull, ull> pull;
typedef pair<double, double> pdd;
/*
深刻理解题意后,解法就是反向建图,topo 找字典序最大的拓扑序列
*/
const int maxm = 1e5 + 5, inf = 0x3f3f3f3f, mod = 998244353;

void solve(){
	int n, m;
	cin >> n >> m;
	bool f = true;
	vector<int> e[n + 1];
	vector<int> ans, in(n + 1, 0);
	for(int i = 0; i < m; ++ i){
		int x, y;
		cin >> x >> y;
		if(find(e[y].begin(), e[y].end(), x) == e[y].end()){
			e[y].push_back(x);
			++ in[x];
		}
	}
	priority_queue<int> q;
	for(int i = 1; i <= n; ++ i){
		if(in[i] == 0) q.push(i);
	}
	while(q.size()){
		int u = q.top(); q.pop();
		ans.push_back(u);
		for(auto v : e[u]){
			-- in[v];
			if(in[v] == 0) q.push(v);
		}
	}
	if(ans.size() == n) f = false;
	if(f) cout << "Impossible!\n";
	else for(int i = n - 1; i >= 0; -- i) cout << ans[i] << " \n"[i == 0];
	return ;
}

signed main(){
	ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
	int _ = 1;
	cin >> _;
	while(_ --){
		solve();
	}
	return 0;
}

标签:toposort,菜肴,顺序,限制,题面,优先,洛谷,尽量,制作
From: https://www.cnblogs.com/Qiansui/p/17590105.html

相关文章

  • 洛谷 P9479 - [NOI2023] 桂花树
    显然,条件一等价于在\(T'\)中,\(1\simn\)组成的虚树等于它本身。条件二等价于\(1\simi\)组成的虚树上点的标号不超过\(i+k\)。我们考虑在原树的基础上依次添加\(n+1\simn+m\)这\(m\)个点。添加一个点\(i\)时,它与原树的位置关系可能有以下几种:挂在原树上某......
  • 洛谷P4407 电子词典
    读完这题我马上就想到了题解trie+dfs的爆搜解法,这种解法思维难度很低,算个模拟,很容易想到但是我们稍微计算一下复杂度,就可以发现达到了\(1e8\)级别(\(26*20*20*1e4\),即对于每一个待查字符串(\(1e4\)),枚举每一个位置(\(20\)),每一个位置枚举26个字母(\(26\)),然后再在trie树上匹配(\(20\)))害......
  • 洛谷 P1347 排序 - 拓扑排序
    P1347排序题意依次给一些具有排序关系的序列,问你在能否在若干个序列之后确定元素的顺序、判断元素关系存在矛盾、判断无法确认元素顺序思路对于每一个排序关系均进行toposort,后面就是toposort判环(出现矛盾),toposort判顺序,无法确认唯一关系。详见代码或看洛谷题解区代码......
  • [百紫祭] 洛谷P5840做题笔记
    [百紫祭]洛谷P5840做题笔记luogu传送门前置芝士:AC自动机,树上差分,树剖求LCA,树状数组。前言一篇笔记需要一张头图。题意给出\(n\)个字符串\(S_1,S_2\.\.\.\S_n\)和一个初始为空的字符串集合\(T\),接下来\(q\)次操作。操作分为修改和询问。修改操作为向\(T\)中......
  • 洛谷 P2894 [USACO08FEB] Hotel G 题解
    题目链接P2894[USACO08FEB]HotelG-洛谷|计算机科学教育新生态(luogu.com.cn)分析考虑用线段树维护区间信息维护sum(最大连续空房间数)如何合并?sum1为max(sum2,sum3)(1的两个子区间)但我们发现若区间为100001(0表示空房间)sum1=4而max(sum2,sum3)=2所以再维护suml(从左开始的......
  • 洛谷 P9221 「TAOI-1」Pentiment 题解
    Description给定\(n\timesm\)的矩阵,从第\(1\)行任意格子出发,每次向下、左、有走一步,有\(q\)个障碍不能经过,求走到第\(n\)行任意格子的方案。对于所有数据,\(1\leqn,m\leq10^9\),\(1\leqq\leq10^5\)。link:https://www.luogu.com.cn/problem/P9221Solution算法一考......
  • 洛谷 P3291 [SCOI2016] 妖怪
    设每只怪物经过环境影响后的攻击力和防守力分别为\(x_i,y_i\),则有:\(y_i=dnf_i-\dfracba(x_i-atk_i)\)。设\(k=-\dfracba\),则有\(y_i=kx_i+dnf_i-k\cdotatk_i\)。设直线\(l_i:y_i=kx_i+dnf_i-k\cdotatk_i\),第\(i\)只怪物在\((a,b)\)的环境下......
  • 洛谷P3629 [APIO2010] 巡逻题解
    题目链接P3629[APIO2010]巡逻-洛谷|计算机科学教育新生态(luogu.com.cn)思路n个村庄,n-1条道路,原图为树1.若k=0(不修建道路)那么答案为(n-1)*2 每个道路会走两遍2.若k为1(修建一条道路)设修建的道路(r1)所在的环长度为L那么答案为(n-1)*2-L+2可以看到r1所在环的道路只走了......
  • 洛谷CF1738C题解
    好一道博弈论水题题目传送门更好的食用体验题目大意:给定长度为$n$的数列$a_1,a_2,\dots,a_n$,两名玩家Alice、Bob依次以最优策略从数列中取走一个数,Alice先取,直至为空博弈结束。若Alice取走的所有数之和为偶,Alice胜利;若Alice取走的所有数之和为奇,Bob胜利......
  • 洛谷 T356695 文字处理软件(重置版)
    很简单了啊!说普及-我都不信作者(也就是我)链接:https://www.luogu.com.cn/problem/T356695好好想想!!!!题目!文字处理软件(重置版)题目背景Allow是一名程序员,他要为公司开发一款“文字处理软件”!题目描述用户可能输入∞个数字。说白了用while(1)输入1时,把字符串原样输出。......