zoukankan      html  css  js  c++  java
  • hdu 5305 回溯+剪枝

    思路:对每一条边涂上颜色1或-1,颜色值加到关联的两个点上,则一种成功的方案必须满足最后每个点的值为0.

    剪枝:统计出和某个点i相关联的边的个数,如果枚举到某一条边的时候发现:abs(sum[i]) > degree[i],则剪去,其中sun[i]表示i点的值,degree[i]表示剩下的还没有枚举的和i关联的边的个数。

     1 #include <iostream>
     2 #include <cstring>
     3 #include <cstdio>
     4 using namespace std;
     5 
     6 const int N = 9;
     7 const int M = 28;
     8 int sum[N];
     9 int degree[N];
    10 int n, m, ans;
    11 
    12 struct Edge
    13 {
    14     int u, v;
    15 } edge[M];
    16 
    17 int judge()
    18 {
    19     for ( int i = 1; i <= n; i++ )
    20     {
    21         if ( sum[i] ) return 0;
    22     }
    23     return 1;
    24 }
    25 
    26 int abs( int x )
    27 {
    28     return x > 0 ? x : -x;
    29 }
    30 
    31 void dfs( int cur )
    32 {
    33     if ( cur == m )
    34     {
    35         ans += judge();
    36         return ;
    37     }
    38     for ( int i = 1; i <= n; i++ )
    39     {
    40         if ( abs(sum[i]) > degree[i] ) return ;
    41     }
    42     int u = edge[cur].u, v = edge[cur].v;
    43     degree[u]--;
    44     degree[v]--;
    45     sum[u]++;
    46     sum[v]++;
    47     dfs( cur + 1 );
    48     sum[u]--;
    49     sum[v]--;
    50     sum[u]--;
    51     sum[v]--;
    52     dfs( cur + 1 );
    53     sum[u]++;
    54     sum[v]++;
    55     degree[u]++;
    56     degree[v]++;
    57 }
    58 
    59 int main ()
    60 {
    61     int t;
    62     scanf("%d", &t);
    63     while ( t-- )
    64     {
    65         scanf("%d%d", &n, &m);
    66         memset( degree, 0, sizeof(degree) );
    67         for ( int i = 0; i < m; i++ )
    68         {
    69             scanf("%d%d", &edge[i].u, &edge[i].v);
    70             degree[edge[i].u]++;
    71             degree[edge[i].v]++;
    72         }
    73         bool flag = false;
    74         for ( int i = 1; i <= n; i++ )
    75         {
    76             if ( degree[i] & 1 )
    77             {
    78                 flag = true;
    79                 break;
    80             }
    81         }
    82         ans = 0;
    83         if ( !flag )
    84         {
    85             memset( sum, 0, sizeof(sum) );
    86             dfs(0);
    87         }
    88         printf("%d
    ", ans);
    89     }
    90     return 0;
    91 }
  • 相关阅读:
    Spinner用法与ListView用法
    ViewPager实现选项卡功能
    android:layout_weight的真实含义
    vb和vb.net事件机制
    go
    挨踢江湖之十一
    蓝桥杯-地铁换乘
    【Android LibGDX游戏引擎开发教程】第06期:图形图像的绘制(下)图片整合工具的使用
    Eclipse3.6 添加JUnit源代码
    【分享】如何使用sublime代码片段快速输入PHP头部版本声明
  • 原文地址:https://www.cnblogs.com/huoxiayu/p/4671757.html
Copyright © 2011-2022 走看看