1、题目大意:给你一棵树,树的每个节点都有一个权值,是0或1,最开始都是0,你可以做一种修改操作,就是把一个节点和它相邻的
节点的权值取反,问最少几次修改能把所有节点的权值变得都是1,最多100个节点

2、分析:经典高斯消元问题,如果i节点的修改能够影响到j节点,那么a[i][j] = 1;(a是系数矩阵)

等式的右边是1。。。对于所有的自由元2^n暴力枚举,然后就AC了, 这题坑了一个礼拜啊,(大神们不要嘲笑我T_T)

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
int a[110][110], is_free[110], p[110], ans[110], end_ans, m, tot;
inline void gauss_elimination(int n){
    for(int i = 1, j = 1; i <= n; i ++, j ++){
        if(j == n + 1){
            m = i - 1;
            return;
        }
        for(int k = i; k <= n; k ++){
            if(a[k][j]){
                for(int h = 1; h <= n + 1; h ++)
                    swap(a[i][h], a[k][h]);
                break;
            }
        }
        if(!a[i][j]){
            is_free[j] = 1;
            tot ++;
            i --;
            continue;
        }
        for(int k = i + 1; k <= n; k ++){
            if(a[k][j]){
                for(int h = j; h <= n + 1; h ++){
                    a[k][h] ^= a[i][h];
                }
            }
        }
    }
    m = n;
    return;
}
int main(){
    int n;
    while(scanf("%d", &n) != EOF){
        if(n == 0) return 0;
        memset(a, 0, sizeof(a));
        memset(is_free, 0, sizeof(is_free));
        memset(ans, 0, sizeof(ans));
        tot = 0;
        end_ans = 2147483647;
        for(int i = 1; i < n; i ++){
            int u, v;
            scanf("%d%d", &u, &v);
            a[u][v] = a[v][u] = 1;
        }
        for(int i = 1; i <= n; i ++) a[i][i] = a[i][n + 1] = 1;
        gauss_elimination(n);
        for(int i = 0; i < (1 << tot); i ++){
            for(int j = 0; j < tot; j ++){
                if(i & (1 << j)) p[j + 1] = 1;
                else p[j + 1] = 0;
            }
            int u = 0;
            for(int j = 1; j <= n; j ++){
                if(is_free[j]){
                    u ++;
                    ans[j] = p[u];
                }
            }
            for(int k = n, j = m; j >= 1; j --){
                for( ; k && is_free[k]; k --);
                ans[k] = a[j][n + 1];
                for(int h = k + 1; h <= n; h ++){
                    if(a[j][h])
                        ans[k] ^= ans[h];
                }
                k --;
            }
            int cnt = 0;
            for(int j = 1; j <= n; j ++) if(ans[j])
                cnt ++;
            end_ans = min(end_ans, cnt);
        }
        printf("%d\n", end_ans);
    }
    return 0;
}

BZOJ2466——[中山市选]树的更多相关文章

  1. [bzoj2466][中山市选2009]树_树形dp

    树  bzoj-2466 中山市选-2009 题目大意:给定一棵树,每一个点有一个按钮和一个灯泡.如果按下一个点的按钮那么和这个点直接相连的点包括这个点的灯泡的状态会改变.如果是点亮就会变成熄灭,如果 ...

  2. bzoj2466: [中山市选2009]树

    同上一题.(应该可以树形dp,然而我不会... #include<cstdio> #include<cstring> #include<iostream> #inc ...

  3. 【dfs】【高斯消元】【异或方程组】bzoj1770 [Usaco2009 Nov]lights 燈 / bzoj2466 [中山市选2009]树

    经典的开关灯问题. 高斯消元后矩阵对角线B[i][i]若是0,则第i个未知数是自由元(S个),它们可以任意取值,而让非自由元顺应它们,得到2S组解. 枚举自由元取0/1,最终得到最优解. 不知为何正着 ...

  4. 【BZOJ2466】[中山市选2009]树 树形DP

    [BZOJ2466][中山市选2009]树 Description 图论中的树为一个无环的无向图.给定一棵树,每个节点有一盏指示灯和一个按钮.如果节点的按扭被按了,那么该节点的灯会从熄灭变为点亮(当按 ...

  5. BZOJ 2466: [中山市选2009]树( 高斯消元 )

    高斯消元解异或方程组...然后对自由元进行暴搜.树形dp应该也是可以的... ------------------------------------------------------------- ...

  6. BZOJ 2467: [中山市选2010]生成树 [组合计数]

    2467: [中山市选2010]生成树 Time Limit: 5 Sec  Memory Limit: 128 MBSubmit: 638  Solved: 453[Submit][Status][ ...

  7. BZOJ_2467_[中山市选2010]生成树_数学

    BZOJ_2467_[中山市选2010]生成树_数学 [Submit][Status][Discuss] Description 有一种图形叫做五角形圈.一个五角形圈的中心有1个由n个顶点和n条边组成 ...

  8. bzoj 2441 [中山市选2011]小W的问题

    bzoj 2441 [中山市选2011]小W的问题 Description 有一天,小W找了一个笛卡尔坐标系,并在上面选取了N个整点.他发现通过这些整点能够画出很多个"W"出来.具 ...

  9. BZOJ 2440: [中山市选2011]完全平方数 [容斥原理 莫比乌斯函数]

    2440: [中山市选2011]完全平方数 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 3028  Solved: 1460[Submit][Sta ...

随机推荐

  1. join的理解

    thread.Join把指定的线程加入到当前线程,可以将两个交替执行的线程合并为顺序执行的线程.比如在线程B中调用了线程A的Join()方法,直到线程A执行完毕后,才会继续执行线程B. t.join( ...

  2. javascript基础之打印乘法表

    废话不多说,直接上代码!! 代码如下: for(var i =1; i<=9;i++){ for(var j =1; j<=i;j++){ document.write(i+"* ...

  3. yum提示another app is currently holding the yum lock;waiting for it to exit

    Another app 解决方法:rm -rf /var/run/yum.pid 来强行解除锁定,然后你的yum就可以运行了

  4. Java——按钮组件:JButton

    import java.awt.Color; import java.awt.Dimension; import java.awt.Font; import java.awt.Point; impor ...

  5. Java反射机制<2>

    反射机制还可以调用类中的指定方法或指定属性,并且可以通过反射完成对数组的操作. 通过反射调用类中的方法 import java.lang.reflect.Method; //============= ...

  6. SVN中Branch和Merge实践

    参考资料:http://blog.csdn.net/eggcalm/article/details/6606520 branch主要用于新功能的开发,开发过程中不断从trunk merge revis ...

  7. Tomcat的目录结构、处理流程、主配置文件(server.xml)释义

    参考资料: http://www.cnblogs.com/xdp-gacl/p/3744053.html http://grass51.blog.51cto.com/4356355/1123400 1 ...

  8. Which is the best opencv or matlab for image processing?

    http://www.researchgate.net/post/Which_is_the_best_opencv_or_matlab_for_image_processing Annette Mor ...

  9. Quartz-2D

    Quartz 2D是一个二维图形绘制引擎,支持iOS环境和Mac OS X环境.我们可以使用Quartz 2D API来实现许多功能,如基本路径的绘制.透明度.描影.绘制阴影.透明层.颜色管理.反锯齿 ...

  10. fedora 23如何实现 让root用户自动登录?

    没想到很简单: 只是修改一个文件的一个地方: 修改: /etc/gdm/custom.conf文件, 将自动登录 启用为true, 然后自动登录的名字设为root 即可: