[DLX精确覆盖] hdu 3663 Power Stations

题意:

给你n、m、d,代表有n个城市,m条城市之间的关系,每个城市要在日后d天内都有电。

对于每个城市,都有一个发电站,每个发电站可以在[a,b]的每一个连续子区间内发电。

x城市发电了,他相邻的城市也有电,并且每个发电站只能启动一次,或者不启动。

现在问,如何安排发电站的启动,保证每个城市d天都有电。

输出发电方案,不发电的话输出0 0

思路:

一个简单的精确覆盖问题,就是建图比较麻烦一点。

这里考虑到每天都要得到电,所以把每个城市每天都设为列(n*d)

然后每个城市对于[a,b]的所有子区间,作为行。

然后对于每个城市只能启动1次,所以需要添加n行,代表每个城市发过点没。

所以列是n*d+n。

还需要注意的是,在判断dance成立的时候,只要判断R[0]==0 || R[0]>n*d

因为每个发电站不一定要发电。

代码:

#include"stdio.h"
#include"algorithm"
#include"string.h"
#include"iostream"
#include"queue"
#include"map"
#include"vector"
#include"string"
using namespace std;
#define N 2010*(66*6)
#define M 2010
int ooo;
struct DLX
{
    int n,m,C;
    int U[N],D[N],L[N],R[N],Row[N],Col[N];
    int H[M],S[M],cnt,ans[M];
    void init(int _n,int _m)
    {
        n=_n;
        m=_m;
        for(int i=0; i<=m; i++)
        {
            U[i]=D[i]=i;
            L[i]=(i==0?m:i-1);
            R[i]=(i==m?0:i+1);
            S[i]=0;
        }
        C=m;
        for(int i=1; i<=n; i++) H[i]=-1;
    }
    void link(int x,int y)
    {
        C++;
        Row[C]=x;
        Col[C]=y;
        S[y]++;
        U[C]=U[y];
        D[C]=y;
        D[U[y]]=C;
        U[y]=C;
        if(H[x]==-1) H[x]=L[C]=R[C]=C;
        else
        {
            L[C]=L[H[x]];
            R[C]=H[x];
            R[L[H[x]]]=C;
            L[H[x]]=C;
        }
    }
    void del(int x)
    {
        R[L[x]]=R[x];
        L[R[x]]=L[x];
        for(int i=D[x]; i!=x; i=D[i])
        {
            for(int j=R[i]; j!=i; j=R[j])
            {
                U[D[j]]=U[j];
                D[U[j]]=D[j];
                S[Col[j]]--;
            }
        }
    }
    void rec(int x)
    {
        for(int i=U[x]; i!=x; i=U[i])
        {
            for(int j=L[i]; j!=i; j=L[j])
            {
                U[D[j]]=j;
                D[U[j]]=j;
                S[Col[j]]++;
            }
        }
        R[L[x]]=x;
        L[R[x]]=x;
    }
    int dance(int x)
    {
        if(R[0]==0 || R[0]>ooo)    //判定条件
        {
            cnt=x;
            return 1;
        }
        int now=R[0];
        for(int i=R[0]; i!=0 && i<=ooo; i=R[i])   //这里注意也要改
        {
            if(S[i]<S[now]) now=i;
        }
        del(now);
        for(int i=D[now]; i!=now; i=D[i])
        {
            ans[x]=Row[i];
            for(int j=R[i]; j!=i; j=R[j]) del(Col[j]);
            if(dance(x+1)) return 1;
            for(int j=L[i]; j!=i; j=L[j]) rec(Col[j]);
        }
        rec(now);
        return 0;
    }
} dlx;
struct node
{
    int a,b;
} kx[66];
struct answer
{
    int id,x,y;
}daan[2002];
int main()
{
    int n,m,d;
    while(scanf("%d%d%d",&n,&m,&d)!=-1)
    {
        ooo=n*d;
        int v[66][66];
        memset(v,0,sizeof(v));
        while(m--)
        {
            int a,b;
            scanf("%d%d",&a,&b);
            v[a][b]=v[b][a]=1;
        }
        int cnt=0;
        for(int i=1; i<=n; i++)
        {
            scanf("%d%d",&kx[i].a,&kx[i].b);
            for(int j=kx[i].a; j<=kx[i].b; j++) for(int k=j; k<=kx[i].b; k++) cnt++;
        }
        dlx.init(cnt,n*d+n);
        cnt=0;
        for(int i=1; i<=n; i++)
        {
            for(int j=kx[i].a; j<=kx[i].b; j++)
            {
                for(int k=j; k<=kx[i].b; k++)
                {
                    ++cnt;
                    daan[cnt].id=i;
                    daan[cnt].x=j;
                    daan[cnt].y=k;
                    for(int l=j; l<=k; l++)
                    {
                        dlx.link(cnt,(i-1)*d+l);
                        for(int u=1;u<=n;u++)
                        {
                            if(v[i][u])
                            {
                                //printf("%d %d %d\n",i,u,l);
                                dlx.link(cnt,(u-1)*d+l);
                            }
                        }
                    }
                    dlx.link(cnt,n*d+i);
                }
            }
        }
        int ans=dlx.dance(0);
        if(ans==0) puts("No solution");
        else
        {
            int us[66];
            memset(us,0,sizeof(us));
            for(int i=0;i<dlx.cnt;i++) us[daan[dlx.ans[i]].id]=dlx.ans[i];
            for(int i=1;i<=n;i++)
            {
                if(us[i]==0) printf("0 0\n");
                else printf("%d %d\n",daan[us[i]].x,daan[us[i]].y);
            }
        }
        puts("");
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-09 20:50:49

[DLX精确覆盖] hdu 3663 Power Stations的相关文章

搜索(DLX):HDU 3663 Power Stations

Power Stations Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2164    Accepted Submission(s): 626Special Judge Problem Description There are N towns in our country, and some of them are connect

[DLX精确覆盖] hdu 1603 A Puzzling Problem

题意: 给你n块碎片,这些碎片不能旋转.翻折. 问你能不能用当中的某些块拼出4*4的正方形. 思路: 精确覆盖裸题了 建图就是看看每一个碎片在4*4中能放哪些位置,这个就作为行. 列就是4*4=16个位置再加上n个碎片也就是16+n 然后注意下成立的判定就好了 代码: #include"stdio.h" #include"algorithm" #include"string.h" #include"iostream" #inc

[DLX精确覆盖] hdu 4210 Su-domino-ku

题意: 首先给你N块板(2*1或1*2)的,数字以及位置 再给你9个单个的板,1~9,分别的位置 然后问你如何放其他板(1*2或2*1)使得成为数独 注意的是对于板子来说,含有的数字是唯一的 也就是含有数字1和2的板有且只有1块 思路: 感觉自己太挫的,写了超级麻烦的建图 列是5*9*9的 前面的4*9*9就和普通的数独一样 后面的9*9是代表放的板的数字 就是对于(i,j)这的数对进行标记 当然需要特殊加入i==j的这些板子. 然后行就是前面的N块以及9个单块,还有9个特殊的 剩下的对于没有出

DLX精确覆盖与重复覆盖模板题

hihoCoder #1317 : 搜索四·跳舞链 原题地址:http://hihocoder.com/problemset/problem/1317 时间限制:10000ms 单点时限:1000ms 内存限制:256MB   描述 小Ho最近遇到一个难题,他需要破解一个棋局. 棋局分成了n行,m列,每行有若干个棋子.小Ho需要从中选择若干行使得每一列有且恰好只有一个棋子. 比如下面这样局面: 其中1表示放置有棋子的格子,0表示没有放置棋子. 对于上面这个问题,小Ho经过多次尝试以后得到了解为选

POJ 3047 Sudoku DLX精确覆盖

DLX精确覆盖.....模版题 Sudoku Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8336   Accepted: 2945 Description In the game of Sudoku, you are given a large 9 × 9 grid divided into smaller 3 × 3 subgrids. For example, . 2 7 3 8 . . 1 . . 1 . .

ZOJ 3209 Treasure Map(DLX精确覆盖)

Your boss once had got many copies of a treasure map. Unfortunately, all the copies are now broken to many rectangular pieces, and what make it worse, he has lost some of the pieces. Luckily, it is possible to figure out the position of each piece in

POJ 3076 Sudoku DLX精确覆盖

DLX精确覆盖模版题..... Sudoku Time Limit: 10000MS   Memory Limit: 65536K Total Submissions: 4416   Accepted: 2143 Description A Sudoku grid is a 16x16 grid of cells grouped in sixteen 4x4 squares, where some cells are filled with letters from A to P (the fi

POJ 3074 Sudoku DLX精确覆盖

DLX精确覆盖.....模版题 Sudoku Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8336   Accepted: 2945 Description In the game of Sudoku, you are given a large 9 × 9 grid divided into smaller 3 × 3 subgrids. For example, . 2 7 3 8 . . 1 . . 1 . .

(简单) HUST 1017 Exact cover , DLX+精确覆盖。

Description There is an N*M matrix with only 0s and 1s, (1 <= N,M <= 1000). An exact cover is a selection of rows such that every column has a 1 in exactly one of the selected rows. Try to find out the selected rows. DLX精确覆盖的模板题...... 代码如下: //HUST 1