HDU - 5823: color II (DP-shaped pressure inversion DP)

The meaning of problems: Given FIG communication, the number of colors determined all sub connectivity graph of FIG. The number of colors in a graph refers to the minimum number of colors, to FIG stained in different colors so that there are points between adjacent edges.

Ideas: First, the idea is to enumerate DFS, and then calculate the color, we found that for a given map, find the color does not seek? After all, it is a mess undirected graph.

  Then consider DP: dp [s] = min (dp [s0] +1), s0 is a subset of s, and satisfies s ^ s0 is set independently. So the complexity is O (3 ^ N);

Because of complement, can also be used inversion DP? ? ? I first met. Good food, ah, I have the opportunity to mend.

#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;
}

 

Guess you like

Origin www.cnblogs.com/hua-dong/p/11232341.html