问题: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

回答:题意大概是英雄可以放一个技能,使得一个点和与其相邻的点受到伤害,问最少攻击几个点能够让所有的点都受到至少一次伤害。

#include<cstdio>
#include<cstring>
#include<climits>
#define N 60
#define M 3600
using namespace std;
struct
{
    int col,row;
} node[M];
int l[M],r[M],d[M],u[M],h[M],res[N],cntcol[N];
int dcnt=-1,minn;
int n,m;
bool visit[N],mark[N][N];
int H()
{
    int count=0;
    bool hash[N];
    memset(hash,false,sizeof(hash));
    for(int i=r[0]; i!=0; i=r[i])
    {
        if(hash[i]) continue;
        //hash[i]=true;
        count++;
        for(int j=d[i]; j!=i; j=d[j])
            for(int k=r[j]; k!=j; k=r[k])
                hash[node[k].col]=true;
    }
    return count;
}
void addnode(int &x)
{
    ++x;
    r[x]=l[x]=u[x]=d[x]=x;
}
void insert_row(int rowx,int x)
{
    r[l[rowx]]=x;
    l[x]=l[rowx];
    r[x]=rowx;
    l[rowx]=x;
}
void insert_col(int colx,int x)
{
    d[u[colx]]=x;
    u[x]=u[colx];
    d[x]=colx;
    u[colx]=x;
}
void dlx_init(int cols)
{
    memset(h,-1,sizeof(h));
    memset(cntcol,0,sizeof(cntcol));
    dcnt=-1;
    addnode(dcnt);
    for(int i=1; i<=cols; ++i)
    {
        addnode(dcnt);
        insert_row(0,dcnt);
    }
}
void insert_node(int x,int y)
{
    //printf("insert %d %d\n",x,y);
    cntcol[y]++;
    addnode(dcnt);
    node[dcnt].row=x;
    node[dcnt].col=y;
    insert_col(y,dcnt);
    if(h[x]==-1) h[x]=dcnt;
    else insert_row(h[x],dcnt);
}
void remove(int c)
{
    for(int i=d[c]; i!=c; i=d[i])
    {
        l[r[i]]=l[i];
        r[l[i]]=r[i];
    }
}
void resume(int c)
{
    for(int i=u[c]; i!=c; i=u[i])
    {
        l[r[i]]=i;
        r[l[i]]=i;
    }
}
void DLX(int deep)
{
    if(deep+H()>=minn) return;
    if(r[0]==0)
    {
        if(minn>deep) minn=deep;
        return;
    }
    int min=INT_MAX,tempc;
    for(int i=r[0]; i!=0; i=r[i])
        if(cntcol[i]<min)
        {
            min=cntcol[i];
            tempc=i;
        }
    for(int i=d[tempc]; i!=tempc; i=d[i])
    {
        if(visit[node[i].row]) continue;
        res[deep]=node[i].row;
        remove(i);
        for(int j=r[i]; j!=i; j=r[j]) remove(j);
        DLX(deep+1);
        for(int j=l[i]; j!=i; j=l[j]) resume(j);
        resume(i);
    }
    return;
}
int main()
{
    int k;
    int a,b;
    for(; ~scanf("%d%d",&n,&m);)
    {
        memset(mark,false,sizeof(mark));
        dlx_init(n);//初始化
        for(; m--;)
        {
            scanf("%d%d",&a,&b);
            mark[a][b]=mark[b][a]=true;
        }
        for(int i=1; i<=n; ++i)
            for(int j=1; j<=n; ++j)
                if(mark[i][j]||i==j)
                    insert_node(i,j);
        minn=INT_MAX;
        DLX(0);
        printf("%d\n",minn);
    }
    return 0;
}

DLX模型问题的更多相关文章

  1. 【转】DLX 精确覆盖 重复覆盖

    问题描述: 给定一个n*m的矩阵,有些位置为1,有些位置为0.如果G[i][j]==1则说明i行可以覆盖j列. Problem: 1)选定最少的行,使得每列有且仅有一个1. 2)选定最少的行,使得每列 ...

  2. POJ 3074 Sudoku (DLX)

    Sudoku Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Statu ...

  3. zoj - 3209 - Treasure Map(精确覆盖DLX)

    题意:一个 n x m 的矩形(1 <= n, m <= 30),现给出这个矩形中 p 个(1 <= p <= 500)子矩形的左下角与右下角坐标,问最少用多少个子矩形能够恰好 ...

  4. DLX 舞蹈链 精确覆盖 与 重复覆盖

    精确覆盖问题:给定一个由0-1组成的矩阵,是否能找到一个行的集合,使得集合中每一列都恰好包含一个1 还有重复覆盖问题 dancing links 是 一种数据结构,用来优化搜索,不算是一种算法.(双向 ...

  5. 关于用舞蹈链DLX算法求解数独的解析

    欢迎访问——该文出处-博客园-zhouzhendong 去博客园看该文章--传送门 描述 在做DLX算法题中,经常会做到数独类型的题目,那么,如何求解数独类型的题目?其实,学了数独的构建方法,那么DL ...

  6. 舞蹈链 DLX

    欢迎访问——该文出处-博客园-zhouzhendong 去博客园看该文章--传送门 舞蹈链是一个非常玄学的东西…… 问题模型 精确覆盖问题:在一个01矩阵中,是否可以选出一些行的集合,使得在这些行的集 ...

  7. Dancing Links DLX

    Dancing Links DLX Dancing Links 用来解精准覆盖问题. 精准覆盖问题有两种版本. 精准覆盖 : 给一个01矩阵,如何选出若干行,使得每列都有且仅有一个1. 可以求最少行数 ...

  8. DLX算法一览

    目录: 1 X思想的了解. 链表的递归与回溯. 具体操作. 优化. 一些应用与应用中的再次优化(例题). 练手题 X思想的了解. 首先了解DLX是什么? DLX是一种多元未饱和型指令集结构,DLX 代 ...

  9. HDU 2295 Radar (二分 + Dancing Links 重复覆盖模型 )

    以下转自 这里 : 最小支配集问题:二分枚举最小距离,判断可行性.可行性即重复覆盖模型,DLX解之. A*的启发函数: 对当前矩阵来说,选择一个未被控制的列,很明显该列最少需要1个行来控制,所以ans ...

随机推荐

  1. Android Studio运行程序出现Session ‘app’: Error Launching activity 解决办法

    session "app":error launching activity 一下两种方法,可以轻松解决: 1. 2.把复选框去除:  

  2. [转]Source Insight使用小技巧小结

    Source Insight是一款强大的代码查看工具,本身支持扩展性很好.下面我们就介绍2个扩展用例. 1.快速打开当前文件所在的目录,这个功能类似于eclipse的easyshell插件,就是能快速 ...

  3. Android Studio系列教程一--下载和安装

    原文链接:http://stormzhang.com/devtools/2014/11/25/android-studio-tutorial1/ 背景 相信大家对Android Studio已经不陌生 ...

  4. sort()和qsort()方法详解

    1,C++自带的自动排序方法:sort(); 要使用此函数只需用#include <algorithm> sort即可使用. sort(begin,end),表示一个范围,例如: int ...

  5. this关键字的使用

    一,表示类中属性 1,没有使用this的情况 class Person{ // 定义Person类 private String name ; // 姓名 private int age ; // 年 ...

  6. Lambda表达式关于like问题(未解决)

    参考文章: http://stackoverflow.com/questions/3616215/like-in-lambda-expression-and-linq 1. c=>c.name. ...

  7. Android开发eclipse运行程序时报timeout的解决方法

    eclipse开发Android程序时,忽然莫名其妙报这个错,之前还好好的.忽然就不行了. Failed to install xxx.apk on device~~~: timeout 尝试过手机里 ...

  8. 替换空格-请实现一个函数,将一个字符串中的空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。

    class Solution { public: void replaceSpace(char *str,int length) { char *tmp; ; int i; ;i<length; ...

  9. 【转】PHP date("Y-m-d H:i:s");获取当前时间 差8小时解决办法

    原因:                                                                                              网络资 ...

  10. 七种css方式让一个容器水平垂直居中

    阅读目录 方法一:position加margin 方法二: diaplay:table-cell 方法三:position加 transform 方法四:flex;align-items: cente ...