zoukankan      html  css  js  c++  java
  • HDU

    题意:给定连通图,求出连通图的所有子图的颜色数。 一个图的颜色数,指最少的颜色数,给图染色,使得有边相邻的点之间颜色不同。

    思路:首先想法是DFS枚举,然后计算颜色,发现对于给定图,求颜色不会求? 毕竟是很乱的无向图。

      那么考虑DP:dp[s]=min(dp[s0]+1),s0是s的子集,且满足s^s0是独立集。 那么复杂度是O(3^N);

    因为有补集,还可以用反演DP???我第一次遇到。好菜啊,有机会补一下。

    #include<bits/stdc++.h>
    #define uint unsigned int
    #define rep(i,a,b) for(int i=a;i<=b;i++)
    using namespace std;
    const int maxn=1000010;
    char c[20][20]; bool vis[maxn];
    int q[maxn],tot,N; uint dp[maxn];
    void check(int S)
    {
        rep(i,0,S) vis[i]=0,dp[i]=1000000000;
        dp[0]=0;
        rep(i,0,S) {
            tot=0; bool F=1;
            rep(j,0,N-1) if(i&(1<<j)) q[++tot]=j;
            rep(j,1,tot){
                if(!F) break;
                rep(k,1,tot)
                 if(c[q[j]][q[k]]=='1') {
                    F=0; break;
                }
            }
            if(F) vis[i]=1;
        }
    }
    int main()
    {
        int T,S;
        scanf("%d",&T);
        while(T--){
            scanf("%d",&N); S=(1<<N)-1;
            rep(i,0,N-1) scanf("%s",c[i]);
            check(S);
            for(int s=1;s<=S;s++){
                for(int i=s;;i=(i-1)&s){
                    if(vis[i^s]){
                      dp[s]=min(dp[s],dp[i]+1);
                    }
                    if(i==0) break;
                }
            }
            uint t=1,ans=0;
            for(int i=1;i<=S;i++){
                t=t*233;
                ans+=t*dp[i];
            }
            cout<<ans<<endl;
        }
        return 0;
    }
  • 相关阅读:
    高斯消元法求逆矩阵
    二分法
    Boost库
    sorts
    排序算法_HeapSort
    粒子系统之概述_20140101
    新年祝福!_20140101
    思维_逆向的魅力2_20131229
    思维_逆向的魅力_20131229
    编码能力的提升?_20131228
  • 原文地址:https://www.cnblogs.com/hua-dong/p/11232341.html
Copyright © 2011-2022 走看看