• 洛谷P1041 传染病控制


    解:搜索......

    我们可以每次选择分支少的搜索,或者说,贪心的搜索当前更优的决策。

    每一层把能剪的点搞出来,按照度数/SIZ排序,然后依次搜索。加个最优化剪枝就完事了。

     1 #include <bits/stdc++.h>
     2 
     3 const int N = 310, INF = 0x3f3f3f3f;
     4 
     5 struct Edge {
     6     int nex, v;
     7 }edge[N << 1]; int tp;
     8 
     9 int e[N], siz[N], in[N], n, ans = INF;
    10 int v[N][N];
    11 bool del[N], vis[N];
    12 
    13 inline bool cmp(const int &a, const int &b) {
    14     //return in[a] > in[b];
    15     return siz[a] > siz[b];
    16 }
    17 
    18 inline void add(int x, int y) {
    19     tp++;
    20     edge[tp].v = y;
    21     edge[tp].nex = e[x];
    22     e[x] = tp;
    23     return;
    24 }
    25 
    26 void DFS_1(int x, int f) {
    27     siz[x] = 1;
    28     for(int i = e[x]; i; i = edge[i].nex) {
    29         int y = edge[i].v;
    30         if(y == f) continue;
    31         DFS_1(y, x);
    32         siz[x] += siz[y];
    33     }
    34     return;    
    35 }
    36 
    37 void DFS(int k, int d) {
    38     if(k >= ans) return;
    39     v[d][0] = 0;
    40     for(int x = 1; x <= n; x++) {
    41         if(del[x] || !vis[x]) continue;
    42         /// vis[x] 
    43         for(int i = e[x]; i; i = edge[i].nex) {
    44             int y = edge[i].v;
    45             if(vis[y] || del[y]) continue;
    46             v[d][++v[d][0]] = y;
    47         }
    48     }
    49     
    50     if(!v[d][0]) {
    51         ans = std::min(ans, k);
    52         return;
    53     }
    54     
    55     std::sort(v[d] + 1, v[d] + v[d][0] + 1, cmp);
    56     for(int i = 1; i <= v[d][0]; i++) {
    57         vis[v[d][i]] = 1;
    58     }
    59     k += v[d][0] - 1;
    60     for(int i = 1; i <= v[d][0]; i++) {
    61         int x = v[d][i];
    62         del[x] = 1;
    63         vis[x] = 0;
    64         DFS(k, d + 1);
    65         vis[x] = 1;
    66         del[x] = 0;
    67     }
    68     for(int i = 1; i <= v[d][0]; i++) {
    69         vis[v[d][i]] = 0;
    70     }
    71     return;
    72 }
    73 
    74 int main() {
    75     
    76 //    freopen("disease.in", "r", stdin);
    77 //    freopen("disease.out", "w", stdout);
    78 
    79     int m;
    80     scanf("%d%d", &n, &m);
    81     for(int i = 1, x, y; i <= m; i++) {
    82         scanf("%d%d", &x, &y);
    83         add(x, y); add(y, x);
    84         in[x]++; in[y]++;
    85     }
    86     DFS_1(1, 0);
    87     vis[1] = 1;
    88     DFS(1, 0);
    89     
    90     printf("%d
    ", ans);
    91     return 0;
    92 }
    AC代码
  • 相关阅读:
    C语言之setjmp
    指针和数组的千丝万缕(二)
    函数和指针的运用
    程序员的几个好的博客地址
    C语言之setjmp
    指针和数组的千丝万缕(二)
    指针和数组的千丝万缕(一)
    函数和指针的运用
    指针和数组的千丝万缕(一)
    poj3300
  • 原文地址:https://www.cnblogs.com/huyufeifei/p/10592866.html
Copyright © 2020-2023  润新知