Board logo

標題: 202409潛力2-校外教學分組libra [打印本頁]

作者: may    時間: 2024-10-20 15:49     標題: 202409潛力2-校外教學分組libra

[attach]20107[/attach]
校外教學分組 (Trip)
問題敘述
校外教學要將N位學生分成3組行動。老師認為如果組內有學生彼此是朋友的話可能會因為聊天導致秩序不好,因此同一組內不能存在有兩位學生彼此是朋友關係。
同時,為了使每一組的導遊負擔儘量一樣,老師也希望「最多人的組」和「最少人的組」人數的差值越小越好。
例如:有N = 5位同學,有M = 5筆學生們的朋友關係。假設學生1和2、學生2和3、學生3和4、學生4和5、學生1和5互為朋友,我們可以將學生1和4分成一組、學生2和5分成一組、學生3獨立成一組,則「最多人的組」有2 人,「最少人的組」有1人,差值為1。這是最小的差值了。
給定M筆學生間的朋友關係,請幫老師計算出分組後「最多人的組」和「最少人的組」人數的最小差值;如果無法分組,請輸出 -1。

輸入格式
第一列有兩個正整數N 與 M (3 ≤ N ≤ 16, M ≤ N×( N-1)/2),表示有N位學生和M筆學生們的朋友關係。接下來M列,每列有兩個相異正整數 X 與 Y (1≤ X, Y ≤ N),兩個正整數間以一個空白間隔,代表學生X和學生Y互相是朋友。輸入不存在重複的朋友關係。
輸出格式
請輸出一個整數,表示分組後「最多人的組」和「最少人的組」人數的最小差值,如果無法分組,輸出-1。
輸入範例1
5 5
1 2
2 3
3 4
4 5
1 5
輸出範例1
1
輸入範例2
4 6
1 2
1 3
1 4
2 3
2 4
3 4
輸出範例2
-1
輸入範例3
6 1
1 2
輸出範例3
0
評分說明
此題目測資分成兩組,每組測資有多筆測試資料,需答對該組所有測試資料才能獲得該組分數,各組詳細限制如下。
第一組 (20 分):N ≤ 4。
第二組 (80 分):無特別限制。
https://zerojudge.tw/ShowProblem?problemid=o627
作者: may    時間: 2024-10-20 20:36

  1. #include <bits/stdc++.h>
  2. using namespace std;

  3. const int maxn = 16 + 1;
  4. const int maxm = maxn * (maxn - 1) / 2;
  5. const int inf = 2147483647;

  6. void dfs(int cur, int n, int m, int *group, const int f[maxm][2], int& ans)
  7. {
  8.         if (cur == n)
  9.         {
  10.                 bool flag = true;
  11.                 for (int i = 0; i < m; ++i)
  12.                 {
  13.                         if (group[f[i][0]] == group[f[i][1]])
  14.                         {
  15.                                 flag = false;
  16.                                 break;
  17.                         }
  18.                 }
  19.                 if (flag == true)
  20.                 {
  21.                         int cnt[3] = {0};
  22.                         for (int i = 0; i < n; ++i)
  23.                         {
  24.                                 ++cnt[group[i]];
  25.                         }
  26.                         ans = min(ans, max({cnt[0], cnt[1], cnt[2]}) - min({cnt[0], cnt[1], cnt[2]}));
  27.                 }
  28.                 return;
  29.         }
  30.         for (int i = 0; i < 3; ++i)
  31.         {
  32.                 group[cur] = i;
  33.                 dfs(cur + 1, n, m, group, f, ans);
  34.         }
  35.         return;
  36. }

  37. int solve(int n, int m, int f[maxm][2])
  38. {
  39.         int group[maxn];
  40.         int ans = inf;
  41.         dfs(0, n, m, group, f, ans);
  42.         if (ans == inf)
  43.         {
  44.                 return -1;
  45.         }
  46.         return ans;
  47. }

  48. int main()
  49. {
  50.         int n, m;
  51.         int f[maxm][2];
  52.         scanf("%d%d", &n, &m);
  53.         for (int i = 0; i < m; ++i)
  54.         {
  55.                 scanf("%d%d", &f[i][0], &f[i][1]);
  56.                 --f[i][0];
  57.                 --f[i][1];
  58.         }
  59.         printf("%d\n", solve(n, m, f));
  60.         return 0;
  61. }
複製代碼





歡迎光臨 種子論壇 | 高雄市資訊培育協會學員討論區 (http://seed.istak.org.tw/) Powered by Discuz! 7.2