[HDU3498] whosyourdaddy

Description

sevenzero liked Warcraft very much, but he haven‘t practiced it for several years after being addicted to algorithms. Now, though he is playing with computer, he nearly losed and only his hero Pit Lord left. sevenzero is angry, he decided to cheat to turn defeat into victory. So he entered "whosyourdaddy", that let Pit Lord kill any hostile unit he damages immediately. As all Warcrafters know, Pit Lord masters a skill called Cleaving Attack and he can damage neighbour units of the unit he attacks. Pit Lord can choice a position to attack to avoid killing partial neighbour units sevenzero don‘t want to kill. Because sevenzero wants to win as soon as possible, he needs to know the minimum attack times to eliminate all the enemys.
Input

There are several cases. For each case, first line contains
two integer N (2 ≤ N ≤ 55) and M (0 ≤ M ≤ N*N),and N is the number of
hostile units. Hostile units are numbered from 1 to N. For the
subsequent M lines, each line contains two integers A and B, that means A
and B are neighbor. Each unit has no more than 4 neighbor units. The
input is terminated by EOF.

Output

One line shows the minimum attack times for each case.

Sample Input

5 4
1 2
1 3
2 4
4 5
6 4
1 2
1 3
1 4
4 5

Sample Output

2
3

传说中的DLX在这里就显现出其与众不同的优势,将同伙连成DLX,然后计算最小值

 1 #include<bits/stdc++.h>
 2 #define FOR(i,p,X) for(int i=X[p];i!=p;i=X[i])
 3 #define For(i,a,b) for(int i=(a),i_end=(b);i<=i_end;++i)
 4 using namespace std;
 5 const int N=60;
 6 int n,m,ans;
 7 vector<int>G[N];
 8 struct DLX{
 9     int L[N*N],R[N*N],U[N*N],D[N*N];
10     int C[N*N],H[N],cnt[N],vis[N],id;
11     void init(){
12         For(i,0,n){
13             cnt[i]=0;U[i]=D[i]=i;
14             L[i+1]=i;R[i]=i+1;
15         }
16         R[n]=0;id=n+1;
17         memset(H,-1,sizeof(H));
18     }
19     void Link(int r,int c){
20         cnt[c]++;C[id]=c;
21         U[id]=U[c];D[U[c]]=id;
22         D[id]=c;U[c]=id;
23         if(!~H[r]) H[r]=L[id]=R[id]=id;
24         else{
25             L[id]=L[H[r]];R[L[H[r]]]=id;
26             R[id]=H[r];L[H[r]]=id;
27         }
28         id++;
29     }
30     void Remove(int sz){
31         FOR(j,sz,D)L[R[j]]=L[j],R[L[j]]=R[j];
32     }
33     void Resume(int sz){
34         FOR(j,sz,D)L[R[j]]=R[L[j]]=j;
35     }
36     int h(){
37         int res=0;
38         memset(vis,0,sizeof(vis));
39         FOR(i,0,R){
40             if(vis[i])continue;
41             ++res;
42             FOR(j,i,D)FOR(k,j,R)
43                 vis[C[k]]=1;
44         }
45         return res;
46     }
47     void Dance(int k){
48         if(k+h()>=ans)return;
49         int pos=R[0];
50         if(!pos){
51             if(k<ans)ans=k;
52             return;
53         }
54         FOR(i,0,R)if(cnt[pos]>cnt[i])pos=i;
55         FOR(i,pos,D){
56             Remove(i);
57             FOR(j,i,R)Remove(j);
58             Dance(k+1);
59             FOR(j,i,R)Resume(j);
60             Resume(i);
61         }
62     }
63 }dlx;
64 int main(){
65     while(scanf("%d%d",&n,&m)!=-1){
66         dlx.init();
67         For(i,0,n)G[i].clear(),G[i].push_back(i);
68         For(i,1,m){
69             int u,v;
70             scanf("%d%d",&u,&v);
71             G[u].push_back(v);G[v].push_back(u);
72         }
73         For(i,1,n)For(j,0,G[i].size()-1)
74             dlx.Link(i,G[i][j]);
75         ans=n;
76         dlx.Dance(0);
77         printf("%d\n",ans);
78     }
79     return 0;
80 }
时间: 2024-10-24 15:31:44

[HDU3498] whosyourdaddy的相关文章

hdu - 3498 - whosyourdaddy(反复覆盖DLX)

题意:N(2 ≤ N ≤ 55)个点,M(0 ≤ M ≤ N*N)条无向边,删除一个点会把与其相邻的点一起删掉.问最少删几次能够删掉全部点. 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3498 -->>N个点看成 N 个要被覆盖的列,每一个点作为一行,与其相邻的点的位置在这一行中标为 1,还有它自已的位置也标记为 1.. 这就是经典的反复覆盖问题了..于是,DLX上场.. #include <cstdio> #include &l

[DLX重复覆盖] hdu 3498 whosyourdaddy

题意: 给N个怪,M个关系. 每个关系代表a和b是邻居. 然后问每次攻击你可以攻击一个怪以及它的全部邻居 问最少需要几次攻击能把怪全部杀死. 思路: 怪为行和列,然后对面每个怪的邻居都是这个怪的列建图. 也是比较裸的重复覆盖. 代码: #include"cstdlib" #include"cstdio" #include"cstring" #include"cmath" #include"queue" #i

hdu - 3498 - whosyourdaddy(重复覆盖DLX)

题意:N(2 ≤ N ≤ 55)个点,M(0 ≤ M ≤ N*N)条无向边,删除一个点会把与其相邻的点一起删掉,问最少删几次可以删掉所有点. 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3498 -->>N个点看成 N 个要被覆盖的列,每个点作为一行,与其相邻的点的位置在这一行中标为 1,还有它自已的位置也标记为 1.. 这就是经典的重复覆盖问题了..于是,DLX上场.. #include <cstdio> #include <

搜索专讲

搜索专讲 Tags:搜索 https://www.zybuluo.com/xzyxzy/note/1058215 前言 做一个专题肯定是要花点时间的 但是哇,搜索怎么这么多内容?!WTF?! 好吧慢慢刷,待四五月份左右出pdf或ppt的讲义吧 先把题目放上,大家愿意的和我一起做吧 题目 李老师给了一个包 广搜 [x] ?POJ1426-Find The Multiple https://vjudge.net/problem/POJ-1426 [x] POJ2251-Dungeon Master

题单二:图论500

http://wenku.baidu.com/link?url=gETLFsWcgddEDRZ334EJOS7qCTab94qw5cor8Es0LINVaGMSgc9nIV-utRIDh--2UwRLvsvJ5tXFjbdpzbjygEdpGehim1i5BfzYgYWxJmu ==========  以下是最小生成树+并查集=========================[HDU]1213         How Many Tables        基础并查集★1272         小

图论五百题!

生死看淡不服就淦,这才是人生! =============================以下是最小生成树+并查集======================================[HDU]1213 How Many Tables 基础并查集★1272 小希的迷宫 基础并查集★1325&&poj1308 Is It A Tree? 基础并查集★1856 More is better 基础并查集★1102 Constructing Roads 基础最小生成树★1232 畅通工程 基

图论 500题——主要为hdu/poj/zoj

转自——http://blog.csdn.net/qwe20060514/article/details/8112550 =============================以下是最小生成树+并查集======================================[HDU]1213   How Many Tables   基础并查集★1272   小希的迷宫   基础并查集★1325&&poj1308  Is It A Tree?   基础并查集★1856   More i

图论精炼500题

忘了从哪转的了... =============================以下是最小生成树+并查集====================================== [HDU] 1213               How Many Tables                    基础并查集★ 1272               小希的迷宫                     基础并查集★ 1325&&poj1308    Is It A Tree?       

[Python爬虫]高并发cnblogs博客备份工具(可扩展成并行)

并发爬虫小练习. 直接粘贴到本地,命名为.py文件即可运行,运行时的参数为你想要爬取的用户.默认是本博客. 输出是以用户名命名的目录,目录内便是博客内容. 仅供学习python的多线程编程方法,后续会重写成并行爬虫. 爬虫代码如下: 1 # -*- coding:utf-8 -*- 2 from multiprocessing.managers import BaseManager 3 from pyquery import PyQuery 4 import os, sys, urllib 5