【DG特长生2019 T2】【SSL 2890】项目问题
发布日期:2021-05-07 07:02:17 浏览次数:25 分类:精选文章

本文共 1752 字,大约阅读时间需要 5 分钟。

项目问题的解决方案

项目问题是要确保所有工作都能被完成,且至少选用最少的人数。解决方案涉及深度优先搜索和剪枝策略来高效计算最小人数。

项目背景

项目涉及多个工作和可完成这些工作的人,目标是找到最少的人数,使得每个工作都能被完成。每个工作可以由多个人完成,因此需要合理选择人选以覆盖所有工作。

方法思路

  • 问题分析:每个工作可以由多个人完成,要求至少选用一个能完成每个工作的人。
  • 剪枝策略:如果一个工作只能由一个人完成,直接选择该人,减少后续计算量。
  • 深度优先搜索(DFS):用于枚举工作和对应的人,避免重复计算,提高效率。
  • 剪枝优化:在DFS前,处理只能由一个人完成的工作,直接标记该人,减少工作量。
  • 代码实现

    #include 
    #include
    #include
    using namespace std;int n, w, ans = 1e8;int a[61][11], candu[61][61];int in[61], num, ew;bool doit[61];void work(int number, int now) { if (number >= ans) return; if (now > n) { ans = min(ans, number); return; } if (in[now]) { work(number, now + 1); return; } for (int i = 1; i <= candu[now][0]; i++) { int person = candu[now][i]; if (doit[person]) continue; for (int j = 1; j <= a[person][0]; j++) in[a[person][j]]++; work(number + 1, now + 1); for (int j = 1; j <= a[person][0]; j++) in[a[person][j]]--; }}bool cmp(int x, int y) { return a[x][0] > a[y][0];}int main() { scanf("%d %d", &n, &w); for (int i = 1; i <= w; i++) { scanf("%d", &a[i][0]); for (int j = 1; j <= a[i][0]; j++) scanf("%d", &a[i][j]), candu[a[i][j]][++candu[a[i][j]][0]] = i; } for (int i = 1; i <= n; i++) { if (candu[i][0] == 1 && !in[i]) { ew++; int person = candu[i][1]; doit[person] = 1; for (int j = 1; j <= a[person][0]; j++) in[a[person][j]]++; } } work(0, 1); printf("%d", ans + ew); fclose(stdin); fclose(stdout); return 0;}

    解决思路

  • 剪枝优化:处理只能由一个人完成的工作,直接标记该人,减少后续计算。
  • DFS枚举:通过深度优先搜索枚举工作和对应的人,避免重复计算,提高效率。
  • 覆盖所有工作:确保每个工作至少有一个被选中的人能完成。
  • 结果输出

    代码计算并输出最少需要的人数,确保所有工作都能被完成。

    上一篇:【DG特长生2019 T4】【SSL 2892】文档恢复
    下一篇:【DG特长生2019 T1】【SSL 2889】散步

    发表评论

    最新留言

    表示我来过!
    [***.240.166.169]2025年04月29日 15时19分50秒