• [HDOJ3663]Power Stations


    建立精确覆盖模型求解(Dancing Links)~

    View Code
    1 #include <cstdio>
    2 #include <cstring>
    3 #include <algorithm>
    4
    5  using namespace std;
    6
    7  const int MAXR = 1024;
    8 const int MAXC = 512;
    9 const int SIZE = 1024;
    10 const int INF = (1 << 20);
    11
    12 struct Node
    13 {
    14 Node * u;
    15 Node * d;
    16 Node * l;
    17 Node * r;
    18 int rnum;
    19 int cnum;
    20 };
    21
    22 int node;
    23 int sum[MAXC];
    24 Node head;
    25 Node row[MAXR];
    26 Node column[MAXC];
    27 Node pool[MAXR * MAXC];
    28
    29 int alen;
    30 int ans[MAXR];
    31
    32 void InitDLX(int nr,int nc)
    33 {
    34 node = 0;
    35 memset(sum,0,sizeof(sum));
    36 head.r = &column[0];
    37 column[0].cnum = 0;
    38 column[0].l = &head;
    39 column[0].u = column[0].d = &column[0];
    40 for (int i = 1; i < nc; i++)
    41 {
    42 column[i].cnum = i;
    43 column[i-1].r = &column[i];
    44 column[i].l = &column[i-1];
    45 column[i].u = column[i].d = &column[i];
    46 }
    47 column[nc-1].r = &head;
    48 head.l = &column[nc-1];
    49
    50 for (int i = 0; i < nr; i++)
    51 row[i].l = row[i].r = &row[i];
    52 }
    53
    54 void InsertDLX(int r,int c)
    55 {
    56 sum[c]++;
    57 pool[node].rnum = r;
    58 pool[node].cnum = c;
    59 pool[node].l = row[r].l;
    60 pool[node].r = &row[r];
    61 row[r].l->r = &pool[node];
    62 row[r].l = &pool[node];
    63 pool[node].u = column[c].u;
    64 pool[node].d = &column[c];
    65 column[c].u->d = &pool[node];
    66 column[c].u = &pool[node];
    67
    68 node++;
    69 }
    70
    71 void DeleteRowHeadDLX(int nr)
    72 {
    73 for (int i = 0; i < nr; i++)
    74 {
    75 row[i].l->r = row[i].r;
    76 row[i].r->l = row[i].l;
    77 }
    78 }
    79
    80 void RemoveColumn(Node * col)
    81 {
    82 col->l->r = col->r;
    83 col->r->l = col->l;
    84 for (Node * p = col->d; p != col; p = p->d)
    85 for (Node * q = p->r; q != p; q = q->r)
    86 {
    87 q->u->d = q->d;
    88 q->d->u = q->u;
    89 sum[q->cnum]--;
    90 }
    91 }
    92
    93 void ResumeColumn(Node * col)
    94 {
    95 col->l->r = col;
    96 col->r->l = col;
    97 for (Node * p = col->d; p != col; p = p->d)
    98 for (Node * q = p->r; q != p; q = q->r)
    99 {
    100 q->u->d = q;
    101 q->d->u = q;
    102 sum[q->cnum]++;
    103 }
    104 }
    105
    106 bool dfs(int k)
    107 {
    108 if (head.r == &head)
    109 {
    110 alen = k;
    111 return true;
    112 }
    113
    114 int minl = INF;
    115 Node * mincol;
    116 for (Node * p = head.r; p != &head; p = p->r)
    117 if (sum[p->cnum] < minl)
    118 {
    119 minl = sum[p->cnum];
    120 mincol = p;
    121 }
    122 RemoveColumn(mincol);
    123 for (Node * p = mincol->d; p != mincol; p = p->d)
    124 {
    125 for (Node * q = p->r; q != p; q = q->r)
    126 RemoveColumn(&column[q->cnum]);
    127 if (dfs(k + 1))
    128 {
    129 ans[k] = p->rnum;
    130 return true;
    131 }
    132 for (Node * q = p->l; q != p; q = q->l)
    133 ResumeColumn(&column[q->cnum]);
    134 }
    135 ResumeColumn(mincol);
    136 return false;
    137 }
    138
    139 bool gmap[SIZE][SIZE];
    140
    141 int lable[SIZE];
    142
    143 int main()
    144 {
    145 int nv;
    146 int ne;
    147 int nd;
    148
    149 int nr;
    150 int nc;
    151
    152 int u;
    153 int v;
    154 int o;
    155
    156 while(scanf("%d %d %d",&nv,&ne,&nd) != EOF)
    157 {
    158 nr = 0;
    159 nc = nv + nd * nv;
    160 memset(gmap,false,sizeof(gmap));
    161
    162 for(int i = 0; i < ne; i++)
    163 {
    164 scanf("%d %d",&u,&v);
    165 gmap[u - 1][v - 1] = gmap[v - 1][u - 1] = true;
    166 }
    167
    168 for(int i = 0; i < nv; i++)
    169 gmap[i][i] = true;
    170
    171 for(int i = 0; i < nv; i++)
    172 {
    173 scanf("%d %d",&u,&v);
    174
    175 u--;
    176 v--;
    177
    178 for(int s = u; s <= v; s++)
    179 for(int e = s; e <= v; e++)
    180 lable[nr++] = i * 100 + s * 10 + e;
    181
    182 lable[nr++] = i * 100 + nd * 10 + nd;
    183 }
    184
    185 InitDLX(nr,nc);
    186
    187 for(int i = 0; i < nr; i++)
    188 {
    189 o = lable[i] / 100;
    190 u = (lable[i] % 100) / 10;
    191 v = lable[i] % 10;
    192
    193 InsertDLX(i,o);
    194
    195 if(u == nd && v == nd) continue;
    196
    197 for(int j = 0; j < nv; j++)
    198 if(gmap[o][j])
    199 for(int k = u; k <= v; k++)
    200 InsertDLX(i,nv + j * nd + k);
    201 }
    202
    203 DeleteRowHeadDLX(nr);
    204
    205 if(!dfs(0)) printf("No solution\n");
    206 else
    207 {
    208 sort(ans,ans + alen);
    209 for(int i = 0; i < alen; i++)
    210 {
    211 u = (lable[ans[i]] % 100) / 10;
    212 v = lable[ans[i]] % 10;
    213 if(u == nd && v == nd) printf("0 0\n");
    214 else printf("%d %d\n",u + 1,v + 1);
    215 }
    216 }
    217 printf("\n");
    218 }
    219 return 0;
    220 }
  • 相关阅读:
    QtCreator 常用快捷键
    Qt 键值对照表
    数据管理类设计与实现
    linux free 命令下free/available区别
    Google “战败”后,C++20 用微软的提案进入协程时代!
    怎么看源代码?
    一文教你如何高效使用C语言
    用 gdb 学 C 语言
    Java中 BigDecimal,80%的人都用错了....
    C++11 实现的 100行 线程池
  • 原文地址:https://www.cnblogs.com/debugcool/p/HDOJ3663.html
Copyright © 2020-2023  润新知