题目链接:魔术球问题

 

蒟蒻认为本题的关键还是在一个边与点的关系

本题一看就是图论…当然不少人(包括蒟蒻 是学习网络流来的…

 

显然我们要对球或杆进行操作

由于关系的建立条件是球的相邻放置条件

所以以球为元素建图 而一个杆子就是一条从起点到终点的路径

那么 最多能放的杆子数就是最小路径覆盖数

但是网络流维护的是边的关系

所以我们使用点拆边技能

把入度边和出度边分两个点存 然后在这两个点中间连一条路

 

注:公式:最小路径覆盖数=点数-最大匹配数

 

问题是题目给的是柱子数啊!

然鹅 对于能放的球数增加 柱子的数量单调增

因为球从下向上放 能放的球多了柱子数不可能减啊

 

debug中的错误:

1.    S,T定太小 冲突  数组定太小

2.    反向边初始容量为0

3.    把next定成bool型。。。

 

 1 int main(){
 2     scanf("%d", &n);
 3     int cnt = 0, now = 0;
 4     memset(head, -1, sizeof(head));
 5     memset(next, -1, sizeof(next));
 6     S = N - 3, T = N - 2;
 7     while(cnt <= n){
 8         now++;
 9         addedge(S, now << 1, 1); addedge(now << 1 | 1, T, 1);
10         for(int i = sqrt(now) + 1; i * i < (now << 1); i++)
11             addedge((i * i - now) << 1, now << 1 | 1, 1);
12         if(!dinic()) ub[++cnt] = now;     
13     }
14     printf("%d\n", --now);
15     for(int i = 1; i <= now; i++){
16         if(!vis[i]){
17             int k = i;
18             while(k < (S >> 1) && k != -1 && !vis[k]){
19                 printf("%d ", k);
20                 vis[k] = 1;
21                 k = next[k];
22             }
23             printf("\n");
24         }
25     }
26     return 0;    
27 }
关键部分

相关文章:

  • 2022-12-23
  • 2021-12-26
  • 2021-11-28
  • 2021-07-13
  • 2021-10-23
猜你喜欢
  • 2021-06-25
  • 2018-09-14
  • 2021-10-08
  • 2022-03-09
  • 2021-09-03
相关资源
相似解决方案