HDOJ3663-Power Stations,DLX精确覆盖

//*********************
//Source: HDOJ 3663
//Method: Dancing links
//Author: yihuikang
//*********************
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;

const int NN=1000;
const int MM=1000000;
const int INF=0xfffffff;

struct node{
    int id,l,r;
} q[NN],ans[NN];

int n,m,d,cnt,N,M;
int a[NN],b[NN];
int S[NN],V[NN];
int L[MM],R[MM],U[MM],D[MM],C[MM],H[MM];
bool mp[NN][NN];

void add(int i,int j)
{
    cnt++;
    H[cnt]=i;
    C[cnt]=j;
    S[j]++;

    D[cnt]=j;
    U[cnt]=U[j];
    if (V[i]) R[cnt]=V[i],L[cnt]=L[V[i]];
    else      R[cnt]=L[cnt]=cnt;
    V[i]=cnt;

    U[D[cnt]]=cnt;
    D[U[cnt]]=cnt;
    R[L[cnt]]=cnt;
    L[R[cnt]]=cnt;
}

void link_build()
{
    cnt=n*(d+1);
    for (int i=0; i<=cnt; i++)
    {
        S[i]=0;
        U[i]=D[i]=C[i]=i;
        R[i]=i+1;
        L[i+1]=i;
    }
    L[0]=cnt; R[cnt]=0;

    memset(V,0,sizeof(V));

    N=n;
    for (int u=1; u<=n; u++)
    {
        add(u,u+n*d);
        q[u].id=u; q[u].l=q[u].r=0;
    }//一个站可以始终不供电
    for (int u=1; u<=n; u++)
      for (int l=a[u]; l<=b[u]; l++)
        for (int r=l; r<=b[u]; r++)
        {
            N++;
            add(N,u+n*d);//一个站最多只能工作一段完整的时间段
            q[N].id=u; q[N].l=l; q[N].r=r;
            for (int v=1; v<=n; v++) if (mp[u][v])
              for (int j=l; j<=r; j++) add(N,v+(j-1)*n);//u在第j天向v供电
        }
}

void remove(int c)
{
    R[L[c]]=R[c];
    L[R[c]]=L[c];
    for (int i=D[c]; i!=c; i=D[i])
        for (int j=R[i]; j!=i; j=R[j])
        {
            U[D[j]]=U[j];
            D[U[j]]=D[j];
            S[C[j]]--;
        }
}

void resume(int c)
{
    for (int i=U[c]; i!=c; i=U[i])
        for (int j=L[i]; j!=i; j=L[j])
        {
            D[U[j]]=j;
            U[D[j]]=j;
            S[C[j]]++;
        }
    L[R[c]]=R[L[c]]=c;
}

bool dance()
{
    if (!R[0]) return 1;

    int s(INF),c;
    for (int i=R[0]; i!=0; i=R[i]) if (S[i]<s) s=S[i],c=i;
    if (s==0) return 0;

    remove(c);
    for (int i=D[c]; i!=c; i=D[i])
    {
        ans[q[H[i]].id]=q[H[i]];
        for (int j=R[i]; j!=i; j=R[j]) remove(C[j]);
        if (dance()) return 1;
        for (int j=L[i]; j!=i; j=L[j]) resume(C[j]);
    }
    resume(c);

    return 0;
}

void print_ans()
{
    for (int i=1; i<=n; i++) printf("%d %d\n",ans[i].l,ans[i].r);
    puts("");
}

int main()
{
    int u,v;
    while (scanf("%d%d%d",&n,&m,&d)!=EOF)
    {
        memset(mp,0,sizeof(mp));
        for (int i=1; i<=m; i++)
        {
            scanf("%d%d",&u,&v);
            mp[u][v]=mp[v][u]=1;
        }
        for (int i=1; i<=n; i++)
        {
            mp[i][i]=1; //自己可以给自己供电
            scanf("%d%d",&a[i],&b[i]);
        }

        link_build();
        if (!dance()) puts("No solution\n");
        else          print_ans();
        //WA sereral times because of lack of blanks!!!
    }
    return 0;
}

你可能感兴趣的:(c,工作,Build)