`
暴风雪
  • 浏览: 390921 次
  • 性别: Icon_minigender_2
  • 来自: 杭州
社区版块
存档分类
最新评论

[2-sat][位运算]zoj 3656:Bit Magic

阅读更多

大致题意:
    给出下面一段代码

    很明显这段代码是用a[n]数组来计算出b[n][n]。

void calculate(int a[N], int b[N][N]) {
	for (int i = 0; i < N; ++i) {
		for (int j = 0; j < N; ++j) {
			if (i == j) b[i][j] = 0;
			else if (i % 2 == 1 && j % 2 == 1) b[i][j] = a[i] | a[j];
			else if (i % 2 == 0 && j % 2 == 0) b[i][j] = a[i] & a[j];
			else b[i][j] = a[i] ^ a[j];
		}
	}
}

 现在给出b[n][n]数组,求是否存在一个合法的a[n]数组,使其能计算出已经给出的b[][];

 

大致思路:

    2-sat的思路很容易想到,就是考虑所有数字的31个位,对所有的位分为两组-----这个位是0,这个位是1,再按照上面的代码建立逻辑关系,再建图2-sat。

 

#include<iostream>
#include<cstdio>
#include <algorithm>
#include<cstring>
using namespace std;
const int inf=1<<30;
const int nMax=6000;
const int mMax=1000010;
class edge{
public:
    int v,nex;
};edge e[mMax];
int k,head[nMax];//head[i]是以点i为起点的链表头部

void addedge(int a,int b){//向图中加边的算法,注意加上的是有向边//b为a的后续节点既是a---->b
    e[k].v=b;
    e[k].nex=head[a];
    head[a]=k;k++;
}

int dfn[nMax],low[nMax],sta[nMax],top,atype,belon[nMax],dep;   //atype 强连通分量的个数
bool insta[nMax];

void Tarjan(int u){                 //我的Tarjan模版
    int i,j;
    dfn[u]=low[u]=++dep;
    sta[++top]=u;
    insta[u]=1;
    for(i=head[u];i;i=e[i].nex){
        int v=e[i].v;
        if(!dfn[v]){
            Tarjan(v);
            low[u]=min(low[u],low[v]);
        }
        else{
            if(insta[v])low[u]=min(low[u],dfn[v]);
        }
    }
    if(dfn[u]==low[u]){
        atype++;              //强连通分量个数
        do{
            j=sta[top--];
            belon[j]=atype;   //第j个点属于第type个连通块
            insta[j]=0;
        }while(u!=j);
    }
}

void init(){
    k=1;
    dep=1;
    top=atype=0;
    memset(insta,0,sizeof(insta)); //是否在栈中
    memset(head,0,sizeof(head));   //静态链表头指针
    memset(low,0,sizeof(low));     //Tarjan的low数组
    memset(dfn,0,sizeof(dfn));     //Tarjan的dfn数组
    memset(belon,0,sizeof(belon)); //记录每个点属于哪一个强连通分量
}

int n,m;
int mtx[600][600];
bool judge(){
    for(int i=0;i<n;i++){
        if(belon[i]==belon[i+n]){
            return 0;
        }
    }
    return 1;
}
int main(){
    int i,j,m,a1,a2,num;
    while(scanf("%d",&n)!=EOF)
    {
        for(i=0;i<n;i++)
        {
            for(j=0;j<n;j++)
            {
                scanf("%d",&mtx[i][j]);
            }
        }
        bool flag=1;
        for(i=0;i<n;i++)
        {
            for(j=0;j<n;j++)
            {
                if(mtx[i][j]!=mtx[j][i])
                {
                    flag=0;
                    break;
                }
                if(i==j&&mtx[i][j]!=0)
                {
                    flag=0;
                    break;
                }
            }
        }
        if(!flag)
        {
            cout<<"NO\n";
            continue;
        }
        flag=1;
        int left;
        for(left=0;left<31;left++)
        {
            num=n;
            init();
            for(i=0;i<n;i++)
            {
                for(j=0;j<n;j++)
                {
                    m=mtx[i][j]&(1<<left);
                    if(i==j)continue;
                    else if (i % 2 == 1 && j % 2 == 1)   //// |
                    {
                        a1=i;
                        a2=j;
                        if(m!=0)
                        {
                            addedge(a1+num,a2);
                            addedge(a2+num,a1);
                        }
                        else
                        {
                            addedge(a1,a1+num);
                            addedge(a2,a2+num);
                        }
                    }
                    else if (i % 2 == 0 && j % 2 == 0)    //////&
                    {
                        a1=i;
                        a2=j;
                        if(m!=0)
                        {
                            addedge(a1+num,a1);
                            addedge(a2+num,a2);
                        }
                        else
                        {
                            addedge(a1,a2+num);
                            addedge(a2,a1+num);
                        }
                    }
                    else                                 /////   ^
                    {
                        a1=i;
                        a2=j;
                        if(m!=0)
                        {
                            addedge(a1,a2+num);
                            addedge(a2,a1+num);
                            addedge(a1+num,a2);
                            addedge(a2+num,a1);
                        }
                        else
                        {
                            addedge(a1,a2);
                            addedge(a2,a1);
                            addedge(a1+num,a2+num);
                            addedge(a2+num,a1+num);
                        }
                    }
                }
            }

            for(i=0;i<num*2;i++)
            {
                if(!dfn[i])Tarjan(i);
            }
            n=num;
            if(!judge())
            {
                flag=0;
                break;
            }
        }

        if(flag)printf("YES\n");
        else printf("NO\n");
    }
    return 0;
}
 
0
1
分享到:
评论

相关推荐

    ACM算法经典书籍----最全最详细的书籍推荐!

    2. **进阶**: *Algorithm Design* 或者 *Concrete Mathematics* 3. **深入**: TAOCP 或者 *An Introduction to Probability Theory and Its Applications* 4. **实战**: 参加在线编程比赛如ACM-ICPC等,练习实际...

    在线判断-算法题

    ### 2. 洛谷 (Luogu) - **特点**:国内知名的在线编程学习平台之一,拥有庞大的题库。 - **适用对象**:初学者至高手级别的程序员。 - **优势**:社区活跃度高,用户间交流频繁,便于解决疑问。 ### 3. HDUOJ (Hdu...

    ACM练习题库

    - 大数运算(高精度加减乘除) - 二分查找 - 叉乘、判断线段相交 - BFS(广度优先搜索)、DFS(深度优先搜索) - 数学基础知识(辗转相除法、线段交点计算、多边形面积计算) 2. **高级算法训练**: - 匈牙利...

    ZOJ全部题目分类(分得很细哦)

    ### ZOJ全部题目分类详解 #### 一、概述 ZOJ(Zhejiang Online Judge)作为一项在线编程竞赛平台,提供了丰富的算法题目供学习者练习。本文将根据所提供的文件中的“初学者题”、“模拟问题”、“动态规划”及...

    OnlineJudge站点网址

    #### 2.2 Zhejiang University ACM Online Judge (ZOJ) - **网址**: http://acm.zju.edu.cn - **特点**: - 由浙江大学维护,题目难度适中,适合练习ACM竞赛题目。 - 界面简洁,易于上手。 #### 2.3 Sichuan ...

    在线online judge

    **2. Java的局限性** - **优势**: Java作为一种面向对象的语言,在大型项目开发和安全性方面表现优异。 - **劣势**: 对于信息学竞赛而言,Java的输入输出操作相对繁琐,且执行效率远低于C/C++。由于比赛中对Java程序...

    acm新手训练方案新手必备

    ##### 2. 图论算法 - **图的基本概念**:掌握无向图、有向图、邻接矩阵、邻接表等基本概念。 - **最短路径算法**:包括Dijkstra算法、Bellman-Ford算法、Floyd算法等。 - **示例题目**: - POJ 1860: Dijkstra算法...

    浙大acm最新模板!

    2. **组合数学** - **组合公式**:包括组合数的计算公式C(n, k),以及组合恒等式等。 - **排列组合生成**:实现生成所有可能的排列或组合,这对于全搜索和回溯算法非常重要。 这个模板库不仅提供了代码实现,还...

    ZOJ:浙江大学程序在线评测系统.docx

    ZOJ,全称“浙江大学程序在线评测系统”(Zhejiang University Online Judge),是一个提供信息学(算法竞赛)题库及程序评测的网站。以下是关于ZOJ的详细介绍: 一、基本信息 名称:浙江大学程序在线评测系统(ZOJ)...

    国际大学生程序设计竞赛指南—ACM程序设计

    ##### 2. C++ 泛型编程基础 - **概念**: 泛型编程是一种允许函数和类的参数化定义的技术,通过模板 (templates) 实现。 - **优点**: - 提高代码重用性。 - 增强类型安全性。 - 改进代码可读性和维护性。 - **C++ ...

    Acm竞赛常用算法与数据结构

    - **数论算法**:如欧几里得算法(最大公约数)、扩展欧几里得算法(模逆运算)。 3. **ACM竞赛题型**: - **数学问题**:涉及组合数学、数论、几何等。 - **字符串处理**:模式匹配、编辑距离、最长公共前后缀...

    备战ACM资料 DP问题等

    2. **贪心算法(Greedy Algorithm)** - 贪心算法在每一步选择中都采取当前状态下最优的选择,从而希望导致结果全局最优。 - 应用场景:哈夫曼编码、最小生成树等问题。 3. **完全搜索(Complete Search)** - ...

    zoj3464 Rugby Football测试数据

    ### ZOJ 3464 Rugby Football 测试数据解析 #### 标题与描述解析 根据提供的标题和描述“ZOJ 3464 Rugby Football 测试数据”,我们可以了解到这是针对ZOJ(Zhejiang University Online Judge)平台上的一个编号为...

    zoj-cpp.zip_zoj

    【标题】"ZOJ-CPP.zip" 是一个包含ZOJ(在线判题系统ZeroJudge)网站上多个C++编程练习解答的压缩包。这个压缩包的名称表明它专注于C++语言,很可能是一个学习资源,旨在帮助初学者理解和解决动态规划问题。 【描述...

    leetcode中国-Homo-sapiens-ACM-Learning:智人-ACM-学习

    leetcode中国 POJ problems ID Problem C++ 1001 1002 1003 1004 ...ZOJ 1002 8 POJ 1321 9 HDU 1241 (二)树 ID Problem C++ Source 1 LeetCode 100 2 LeetCode 101 3 LeetCode 437 4 LeetCode 235

    欧拉回路题集

    1. **Strange Country II (ZOJ-3332) 竞赛图** - **题目描述**:在一种特殊的图——竞赛图中寻找哈密顿回路。 - **解题思路**:竞赛图中每个节点的入度和出度都为1,因此可以按照顺序构造哈密顿回路。 - **数据...

    zoj 题库 详细解答 解题代码

    2. ZOJ Problem Set – 1037 Gridland 该题目主要考察了数组和矩阵的操作能力,要求解决 Gridland 问题。该问题的解决需要对数组和矩阵的操作有深入的理解。 知识点:数组、矩阵、数组操作、矩阵操作。 3. ZOJ ...

Global site tag (gtag.js) - Google Analytics