列表

详情


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;
}

上一题