zoj 3656 2-sat 不错的题
http://acm.zju.edu.cn/onlinejudge/showProblem.do?
problemId=4879
TLE了一下午。然后没办法了 去搜题解 发现思路跟我的差点儿相同 可是就是我的T 后来扩大了数组 然后AC,无语啊
按我的估算 500个点 开到1000+就够了 可是不够 奇怪不懂......
YES or NO的题,一般就是并查集跟2-sat了 目測这道题并查集写起来更easy
http://blog.csdn.net/u011026968/article/details/10823853
看着道题 poj 3678 看完就能发现,仅仅要将每一位都当做poj3678 执行32次 然后就OK
建图方法跟poj3678一样
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <stack>
#include <iostream>
using namespace std; #define CL(a,b) memset(a,b,sizeof(a))
#define IN(s) freopen(s,"r",stdin) const int MAXN = 6000;
int n,b[505][505];
int head[MAXN],dfn[MAXN],low[MAXN],id[MAXN];
int cnt,scnt;
stack<int>st;
struct Node{
int to,nxt;
}edge[1000010];/// inline void addedge(int u,int v,int k)
{
edge[k].to=v;
edge[k].nxt=head[u];
head[u]=k;
//printf("u=%d v=%d k=%d\n",u,v,k);
}
void tarjan(int u)
{
int v,i,min1=dfn[u]=low[u]=cnt++;
st.push(u);
for(i=head[u];i!=-1;i=edge[i].nxt)
{
v=edge[i].to;
if(dfn[v]==-1)tarjan(v);
min1=min(min1,low[v]);
}
if(min1<low[u]){low[u]=min1;return;}
do
{
v=st.top();
id[v]=scnt;
st.pop();
low[v]=n*2;
}while(v!=u);
scnt++;
} int solve(int pos)
{
CL(dfn,0xff);
CL(id,0xff);
CL(head,0xff);
CL(low,0xff); scnt=cnt=0;
while(!st.empty())st.pop();
int num=0;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
{
if(i==j)continue;///
int f= (b[i][j]>>pos)&1;
//////////
//printf("pos=%d bij=%d f=%d\n",pos,b[i][j],f);
if(i%2 && j%2)
{
if(f)
{
addedge(i,j+n,num++);
addedge(j,i+n,num++); }
else
{ addedge(i+n,i,num++);
addedge(j+n,j,num++);
addedge(i,j,num++);
addedge(j,i,num++);
}
continue;
}
if(i%2==0 && j%2==0)
{
if(f)
{ addedge(i,i+n,num++);
addedge(j,j+n,num++);
addedge(i+n,j+n,num++);
addedge(j+n,i+n,num++);
}
else
{ addedge(j+n,i,num++);
addedge(i+n,j,num++);
}
continue;
}
if(f)
{
addedge(i,j+n,num++);
addedge(j+n,i,num++);
addedge(j,i+n,num++);
addedge(i+n,j,num++);
}
else
{
addedge(i,j,num++);
addedge(j,i,num++);
addedge(i+n,j+n,num++);
addedge(j+n,i+n,num++);
}
}
int flag=1;
for(int i=0;i<n*2;i++)
if(dfn[i] == -1)
{
////////
//printf("tari=%d\n",i);
////////
tarjan(i);
} for(int i=0;i<n;i++)
if(id[i] == id[i+n])//在同一个连通分量
{
flag=0;
break;
}
if(flag)return 1;
else return 0;
} int main()
{
//IN("zoj3656.txt");
while(~scanf("%d",&n))
{
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
scanf("%d",&b[i][j]);
int flag=0;
for(int i=0;i<n;i++)
{
if(b[i][i])
{
flag=2;
puts("NO");
break;
}
}
if(flag==2)continue;
for(int i=0;i<n-1;i++)
for(int j=i+1;j<n;j++)
{
if(b[i][j]!=b[j][i])
{
flag=2;
puts("NO");
break;
}
}
if(flag==2)continue;
for(int i=0;i<32;i++)
{
flag=solve(i);
if(flag==0)break;
}
if(!flag)puts("NO");
else puts("YES");
}
return 0;
}
并查集的做法代码短了非常多 好流弊的样子 http://blog.csdn.net/lasolmi/article/details/38979207
另一种建图方法,网上找的 快了20ms 不是非常理解的说
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <stack>
#include <iostream>
using namespace std; #define CL(a,b) memset(a,b,sizeof(a))
#define IN(s) freopen(s,"r",stdin) const int MAXN = 6000;
int n,b[505][505];
int head[MAXN],dfn[MAXN],low[MAXN],id[MAXN];
int cnt,scnt;
stack<int>st;
struct Node{
int to,nxt;
}edge[1000010];/// inline void addedge(int u,int v,int k)
{
edge[k].to=v;
edge[k].nxt=head[u];
head[u]=k;
//printf("u=%d v=%d k=%d\n",u,v,k);
}
void tarjan(int u)
{
int v,i,min1=dfn[u]=low[u]=cnt++;
st.push(u);
for(i=head[u];i!=-1;i=edge[i].nxt)
{
v=edge[i].to;
if(dfn[v]==-1)tarjan(v);
min1=min(min1,low[v]);
}
if(min1<low[u]){low[u]=min1;return;}
do
{
v=st.top();
id[v]=scnt;
st.pop();
low[v]=n*2;
}while(v!=u);
scnt++;
} int solve(int pos)
{
CL(dfn,0xff);
CL(id,0xff);
CL(head,0xff);
CL(low,0xff); scnt=cnt=0;
while(!st.empty())st.pop();
int num=0;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
{
if(i==j)continue;///
int f= (b[i][j]>>pos)&1;
//////////
//printf("pos=%d bij=%d f=%d\n",pos,b[i][j],f);
if(i%2 && j%2)
{
if(f)
{
//addedge(i,j+n,num++);
//addedge(j,i+n,num++);
addedge(i+n,j,num++);
addedge(j+n,i,num++);
}
else
{
addedge(i,i+n,num++);
addedge(j,j+n,num++);
//addedge(i+n,i,num++);
//addedge(j+n,j,num++);
//addedge(i,j,num++);
//addedge(j,i,num++);
}
continue;
}
if(i%2==0 && j%2==0)
{
if(f)
{
addedge(i+n,i,num++);
addedge(j+n,j,num++); //addedge(i,i+n,num++);
//addedge(j,j+n,num++);
//addedge(i+n,j+n,num++);
//addedge(j+n,i+n,num++);
}
else
{
addedge(i,j+n,num++);
addedge(j,i+n,num++);
//addedge(j+n,i,num++);
//addedge(i+n,j,num++);
}
continue;
}
if(f)
{
addedge(i,j+n,num++);
addedge(j+n,i,num++);
addedge(j,i+n,num++);
addedge(i+n,j,num++);
}
else
{
addedge(i,j,num++);
addedge(j,i,num++);
addedge(i+n,j+n,num++);
addedge(j+n,i+n,num++);
}
}
int flag=1;
for(int i=0;i<n*2;i++)
if(dfn[i] == -1)
{
////////
//printf("tari=%d\n",i);
////////
tarjan(i);
} for(int i=0;i<n;i++)
if(id[i] == id[i+n])//在同一个连通分量
{
flag=0;
break;
}
if(flag)return 1;
else return 0;
} int main()
{
//IN("zoj3656.txt");
while(~scanf("%d",&n))
{
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
scanf("%d",&b[i][j]);
int flag=0;
for(int i=0;i<n;i++)
{
if(b[i][i])
{
flag=2;
puts("NO");
break;
}
}
if(flag==2)continue;
for(int i=0;i<n-1;i++)
for(int j=i+1;j<n;j++)
{
if(b[i][j]!=b[j][i])
{
flag=2;
puts("NO");
break;
}
}
if(flag==2)continue;
for(int i=0;i<32;i++)
{
flag=solve(i);
if(flag==0)break;
}
if(!flag)puts("NO");
else puts("YES");
}
return 0;
}
zoj 3656 2-sat 不错的题的更多相关文章
- ZOJ Monthly, June 2014 月赛BCDEFGH题题解
比赛链接:点击打开链接 上来先搞了f.c,,然后发现状态不正确,一下午都是脑洞大开,, 无脑wa,无脑ce...一样的错犯2次.. 硬着头皮搞了几发,最后20分钟码了一下G,不知道为什么把1直接当成不 ...
- POJ1062不错的题——spfa倒向建图——枚举等级限制
POJ1062 虽然是中文题目但是还是有一定几率都不准题目意思的:1.所有可能降价的措施不是降价多少钱而是降至多少钱2.等级范围:是你所走的那一条路中所有人中最好最低等级差不允许超过limit限制 思 ...
- ZOJ 3992 One-Dimensional Maze(思维题)
L - One-Dimensional Maze Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%lld & % ...
- ZOJ 3983 Crusaders Quest(思维题)
C - Crusaders Quest Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%lld & %llu S ...
- ZOJ 3778 C - Talented Chef 水题
LINK:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3778 题意:有n道菜,每道菜需要\(a_i\)道工序,有m个锅可 ...
- HDU1160:FatMouse's Speed(最长上升子序列,不错的题)
题目:http://acm.hdu.edu.cn/showproblem.php?pid=1160 学的东西还是不深入啊,明明会最长上升子序列,可是还是没有A出这题,反而做的一点思路没有,题意就不多说 ...
- ZOJ - 3890 Wumpus(BFS基础题)
Wumpus Time Limit: 2 Seconds Memory Limit: 65536 KB One day Leon finds a very classic game call ...
- ZOJ 1494 Climbing Worm 数学水题
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=494 题目大意: 一只蜗牛要从爬上n英寸高的地方,他速度为u每分钟,他爬完u需要 ...
- ZOJ 3652 Maze 模拟,bfs,读题 难度:2
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4842 要注意题目中两点: 1.在踏入妖怪控制的区域那一刹那,先减行动力,然后才 ...
随机推荐
- R包——ggplot2(二)
关于ggplot包(二) 关于ggplot包(二) 标尺(Scale) 从前面可以看到,画图其实就是在做映射,不管是映射到不同的几何对象上,还是映射各种图形属性.在对图形属性进行映射之后,使用标尺可以 ...
- linux杂记(十二?) 关于账号和密码的二三事
关于密码的二三事 关于账号和密码的二三事 久了不更linux的相关知识,实在是懒得想内容点(纯粹是懒).那么今天就来谈谈关于linux密码和账号的重要概念. 假如你的主机遭到入侵,那么对方的第一个侵入 ...
- poj 3270 置换
poj 置换的应用 黑书原题P248 /** 题意: 给定序列, 将其按升序排列, 每次交换的代价是两个数之和, 问代价最小是多少 思路:1.对于同一个循环节之内的,肯定是最小的与别的交换代价最小 2 ...
- IOS 物理引擎
来自IOS7 by tutorials 下面是个人的一点翻译总结 1,首先在初始化方法李画一个方块 UIView* square = [[UIView alloc] initWithFrame: ...
- Tensorflow的CNN教程解析
之前的博客我们已经对RNN模型有了个粗略的了解.作为一个时序性模型,RNN的强大不需要我在这里重复了.今天,让我们来看看除了RNN外另一个特殊的,同时也是广为人知的强大的神经网络模型,即CNN模型.今 ...
- OSG消锯齿
osg::DisplaySettings::instance()->setNumMultiSamples(); 在osg+mfc下成功实现抗锯齿,在程序初始化的时候,即在osg控制类中,我的 ...
- 基于MDK的ARM-GCC开发环境建立及新唐M0的HID类设备的C++开发
一,下载安装测试arm-none-eabi-gcc编译工具链 1,查看arm-none-eabi-gcc编译工具版本 打开网页:https://sourcery.mentor.com/G ...
- 64位WINDOWS系统环境下应用软件开发的兼容性问题(CPU 注册表 目录)
应用软件开发的64 位WINDOWS 系统环境兼容性 1. 64 位CPU 硬件 目前的64位CPU分为两类:x64和IA64.x64的全称是x86-64,从名字上也可以看出来它和 x86是兼容的,原 ...
- linux shell编程总结
linux shell编程总结 本周学习了unix/linux shell编程,参考的是<LINUX与UNIX Shell 编程指南>,David Tansley著:徐焱,张春萌等译,由机 ...
- Android模拟器PANIC: Could not open:问题解决方法
最主要的就是环境变量没有配置或者我们使用的是绝对路径配置环境变量.这时我们只需要修改一下Android的环境变量就可以了. 具体解决方法如下: ①在环境变量中创建变量名:ANDROID_SDK_HOM ...