CMB6. 卡中心美食家
描述
在卡中心隐藏了很多美食,作为一名资深吃货,楼主告诉你需要去品尝n道美味才能达成“卡中心小小美食家”的成就。这些菜品被标号为 0 到 n-1 。正所谓美食家不是一口吃成个胖子的,每道美味的品尝顺序也是有讲究的,比如西餐的上菜顺序:头盘,汤,副菜,主菜,蔬菜类菜肴,甜品,咖啡或茶。有一些美味需要“前置菜肴”,比如如果你要吃菜品0,你需要先吃菜品1,我们用一个范式来表示这些规则:[0 1]。接下来给你菜品的总数量n和m个“前置菜肴”的范式,请编程输出你为了品尝完所有美味所安排的进餐顺序。可能会有多个正确的顺序,你只要输出一种就可以了。如果不可能品尝完所有美味,返回None。输入描述
输入的第一行为以空格分隔的两个正整数,第一个表示原始美味总数n,第二个表示前置菜肴范式总数m。 其后m行每行均为一个以空格分隔的范式说明,第一列为待吃菜肴的标号,第二列为前置菜肴的标号。输出描述
对每组测试数据,单独输出一行答案,菜肴标号之间用英文逗号分隔。示例1
输入:
4 4 1 0 2 0 3 1 3 2
输出:
只需输出以下任一种结果即可 0,1,2,3 或 0,2,1,3
C++ 解法, 执行用时: 2ms, 内存消耗: 396KB, 提交时间: 2020-09-06
#include <bits/stdc++.h> using namespace std; vector<int> path;//存储吃东西顺序的路径 int n, m; bool found;//是否已找到解 vector<unordered_set<int> > limit;//limit[i]:存吃第i个东西前必须先吃的 bool find(int index, int dest) {//此函数用于搜寻某号食物是否已经吃了 bool ans = false; for (int i = 0; i < index; ++i) { if (path[i] == dest) { ans = true; break; } } return ans; } void dfs(int index) {//深度优先搜索 if (!found) { if (index >= n) {//如果已经到了最后,打印结果并将found置true for (int i = 0; i < n; ++i) printf("%d%c", path[i], i==n-1 ? '\n' : ','); found = true; } else {//否则要作进一步搜索 for (int i = 0; i < n; ++i) { if (find(index, i))//如果编号为i的东西已经吃了,则跳过 continue; bool visitable = true; //visitable用来确定吃i号东西前要先吃的东西有没有吃 for (auto it = limit[i].begin(); it != limit[i].end(); ++it) { if (!find(index, *it)) { visitable = false; break; } } if (visitable) { path[index] = i; dfs(index + 1); } } } } } int main() { while (scanf("%d %d", &n, &m) != EOF) { found = false; path.clear(); path.resize(n, -1); limit.clear(); limit.resize(n); int x, y; for (int i = 0; i < m; ++i) { scanf("%d %d", &x, &y); limit[x].insert(y); } dfs(0); if (!found) printf("None\n"); } return 0; }
C++14 解法, 执行用时: 2ms, 内存消耗: 408KB, 提交时间: 2020-08-11
#include <bits/stdc++.h> using namespace std; int main() { int n, m; scanf("%d%d", &n, &m); vector<vector<int>> graph(n); vector<int> indegree(n, 0); for(int i = 0; i < m; i++) { int u, v; scanf("%d%d", &u, &v); graph[v].push_back(u); indegree[u]++; } queue<int> q; for(int i = 0; i < n; i++) if(indegree[i] == 0) q.push(i); vector<int> ans; while(!q.empty()) { auto w = q.front(); q.pop(); ans.push_back(w); for(int next : graph[w]) { if(--indegree[next] == 0) q.push(next); } } if(ans.size() < n) printf("None\n"); else { for(int i = 0; i < n -1 ; i++) printf("%d,", ans[i]); printf("%d\n", ans.back()); } return 0; }
C++ 解法, 执行用时: 2ms, 内存消耗: 472KB, 提交时间: 2020-08-20
#include <bits/stdc++.h> using namespace std; int main(){ int n,m; cin >> n >> m; map<int,vector<int>> pre; vector<int> count(n,0); for(int i = 0;i<m;i++){ int to,from; cin >> to; cin >> from; if (pre.count(from) <= 0){ pre[from] = vector<int>(); } pre[from].push_back(to); count[to]++; } queue<int> zeros; for(int i = 0;i<n;i++){ if(count[i] == 0){ zeros.push(i); } } vector<int> ans; while(!zeros.empty()){ int now = zeros.front(); zeros.pop(); vector<int> to = pre[now]; for(auto it = to.begin();it != to.end();it++){ count[*it]--; if(count[*it] == 0){ zeros.push(*it); } } ans.push_back(now); } string out; if (ans.size() != n){ cout << "None" << endl; }else{ for(auto it = ans.begin();it != ans.end();it++){ out += to_string((*it)); out += ","; } } cout << out.substr(0,out.length()-1) << endl; }
C++ 解法, 执行用时: 2ms, 内存消耗: 480KB, 提交时间: 2020-07-29
#include <bits/stdc++.h> using namespace std; int main() { int n, m; scanf("%d %d", &n, &m); vector<vector<int>> tmap(n + 5); int *count = new int[n + 5]; memset(count, 0, sizeof(int)*(n+5)); for (int i=0; i<m; i++) { int from, to; scanf("%d %d", &to, &from); tmap[from].push_back(to); count[to]++; } queue<int> zeros; for (int i=0; i<n; i++) { if (count[i] == 0) { zeros.push(i); } } vector<int> ans; while (!zeros.empty()) { int now = zeros.front(); zeros.pop(); vector<int> &tto = tmap[now]; for (vector<int>::iterator it = tto.begin(); it!=tto.end(); it++) { count[*it]--; if (count[*it] == 0) zeros.push(*it); } ans.push_back(now); } string out; if (ans.size() != n) { cout << "None" << endl; } else { for (vector<int>::iterator it = ans.begin(); it != ans.end(); it++) { out += to_string((*it)); out += ","; } } cout << out.substr(0, out.length()-1); return 0; }
C++ 解法, 执行用时: 2ms, 内存消耗: 504KB, 提交时间: 2020-09-03
#include <bits/stdc++.h> using namespace std; vector<int> path;//存储吃东西顺序的路径 int n, m; bool found;//是否已找到解 vector<unordered_set<int> > limit;//limit[i]:存吃第i个东西前必须先吃的 bool find(int index, int dest) {//此函数用于搜寻某号食物是否已经吃了 bool ans = false; for (int i = 0; i < index; ++i) { if (path[i] == dest) { ans = true; break; } } return ans; } void dfs(int index) {//深度优先搜索 if (!found) { if (index >= n) {//如果已经到了最后,打印结果并将found置true for (int i = 0; i < n; ++i) printf("%d%c", path[i], i==n-1 ? '\n' : ','); found = true; } else {//否则要作进一步搜索 for (int i = 0; i < n; ++i) { if (find(index, i))//如果编号为i的东西已经吃了,则跳过 continue; bool visitable = true; //visitable用来确定吃i号东西前要先吃的东西有没有吃 for (auto it = limit[i].begin(); it != limit[i].end(); ++it) { if (!find(index, *it)) { visitable = false; break; } } if (visitable) { path[index] = i; dfs(index + 1); } } } } } int main() { while (scanf("%d %d", &n, &m) != EOF) { found = false; path.clear(); path.resize(n, -1); limit.clear(); limit.resize(n); int x, y; for (int i = 0; i < m; ++i) { scanf("%d %d", &x, &y); limit[x].insert(y); } dfs(0); if (!found) printf("None\n"); } return 0; }