【HDU 3663】 Power Stations

【题目链接】

              http://acm.hdu.edu.cn/showproblem.php?pid=3663

【算法】

          先建图,然后用Dancing Links求解精确覆盖,即可

【代码】

           

#include<bits/stdc++.h>
using namespace std;
#define MAXN 500000

int i,j,k,l,m,cnt,N,M,D,u,v;
bool g[65][65];
struct Time
{
        int s,e;
} ans[65],a[65];
struct info
{
        int l,r,pos;
} R[MAXN];

struct DancingLinks
{
        int n,m,step,size;
        int U[MAXN],D[MAXN],L[MAXN],R[MAXN],Row[MAXN],Col[MAXN];
        int H[MAXN],S[MAXN];
        int ans[MAXN];
        inline void init(int _n,int _m)
        {
                int i;
                n = _n;
                m = _m;
                for (i = 0; i <= m; i++)
                {
                        S[i] = 0;
                        U[i] = D[i] = i;
                        L[i] = i - 1;
                        R[i] = i + 1;
                }
                L[0] = m; R[m] = 0;
                size = m;
                for (i = 1; i <= n; i++) H[i] = -1;
        }        
        inline void link(int r,int c)
        {
                size++;
                Row[size] = r;
                Col[size] = c;
                S[c]++;
                D[size] = D[c];
                U[D[c]] = size;
                U[size] = c;
                D[c] = size;
                if (H[r] < 0) L[size] = R[size] = H[r] = size;
                else
                {
                        R[size] = R[H[r]];
                        L[R[H[r]]] = size;
                        L[size] = H[r];
                        R[H[r]] = size;
                }
        }
        inline void Remove(int c)
        {
                int i,j;
                R[L[c]] = R[c];
                L[R[c]] = L[c];
                for (i = D[c]; i != c; i = D[i])
                {
                        for (j = R[i]; j != i; j = R[j])
                        {
                                D[U[j]] = D[j];
                                U[D[j]] = U[j];
                                S[Col[j]]--;
                        }
                }
        }
        inline void Resume(int c)
        {
                int i,j;
                for (i = U[c]; i != c; i = U[i])
                {
                        for (j = L[i]; j != i; j = L[j])
                        {
                                D[U[j]] = j;
                                U[D[j]] = j;
                                S[Col[j]]++;
                        }
                }
                L[R[c]] = c;
                R[L[c]] = c;
        }
        inline bool solve(int dep)
        {
                int i,j,c;
                if (R[0] == 0)
                {
                        step = dep;
                        return true;
                }
                c = R[0];
                for (i = R[0]; i != 0; i = R[i])
                {
                        if (S[i] < S[c])
                                c = i;
                }
                Remove(c);
                for (i = D[c]; i != c; i = D[i])
                {
                        ans[dep] = Row[i];
                        for (j = R[i]; j != i; j = R[j])
                                Remove(Col[j]);
                        if (solve(dep+1)) return true;        
                        for (j = L[i]; j != i; j = L[j])
                                Resume(Col[j]);
                }
                Resume(c);
                return false;
        }
} DLX;

int main() 
{
        
        while (scanf("%d%d%d",&N,&M,&D) != EOF)
        {
                cnt = 1;
                memset(g,false,sizeof(g));
                DLX.init(N*16,N*D+N);
                for (i = 1; i <= M; i++)
                {
                        scanf("%d%d",&u,&v);
                        g[u][v] = g[v][u] = true;    
                }        
                for (i = 1; i <= N; i++) g[i][i] = true;
                for (i = 1; i <= N; i++) scanf("%d%d",&a[i].s,&a[i].e);
                for (i = 1; i <= N; i++)
                {
                        for (j = a[i].s; j <= a[i].e; j++)
                        {
                                for (k = j; k <= a[i].e; k++)
                                {
                                        DLX.link(cnt,i);
                                        R[cnt] = (info){j,k,i};
                                        for (l = 1; l <= N; l++)
                                        {
                                                if (g[i][l])
                                                {
                                                        for (m = j; m <= k; m++)
                                                        {
                                                                DLX.link(cnt,N+(l-1)*D+m);
                                                        }
                                                }
                                        }
                                        cnt++;
                                }
                        }
                        DLX.link(cnt,i);
                        R[cnt] = (info){0,0,i};
                        cnt++;
                }
                if (!DLX.solve(0)) printf("No solution
");
                else
                {
                        memset(ans,0,sizeof(ans));
                        for (i = 0; i < DLX.step; i++)
                        {
                                ans[R[DLX.ans[i]].pos].s = R[DLX.ans[i]].l;
                                ans[R[DLX.ans[i]].pos].e = R[DLX.ans[i]].r;
                        }
                        for (i = 1; i <= N; i++) printf("%d %d
",ans[i].s,ans[i].e);
                }
                printf("
");
        }
        
        return 0;
    
}
原文地址:https://www.cnblogs.com/evenbao/p/9262461.html