UVALive 5010 Go Deeper 2sat

二分答案,2sat判定。


//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<iostream>
#include<sstream>
#include<cmath>
#include<climits>
#include<string>
#include<map>
#include<queue>
#include<vector>
#include<stack>
#include<set>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
#define pb(a) push(a)
#define INF 0x1f1f1f1f
#define lson idx<<1,l,mid
#define rson idx<<1|1,mid+1,r
#define PI 3.1415926535898
template<class T> T min(const T& a,const T& b,const T& c) {
return min(min(a,b),min(a,c));
}
template<class T> T max(const T& a,const T& b,const T& c) {
return max(max(a,b),max(a,c));
}
void debug() {
#ifdef ONLINE_JUDGE
#else

freopen("in.txt","r",stdin);
//freopen("d:\\out1.txt","w",stdout);
#endif
}
int getch() {
int ch;
while((ch=getchar())!=EOF) {
if(ch!=‘ ‘&&ch!=‘\n‘)return ch;
}
return EOF;
}

const int maxn=205;
struct TwoSat
{
int n;
vector<int> g[maxn*2];
bool mark[maxn*2];
int s[maxn*2],c;
bool dfs(int x)
{
if(mark[x^1])return false;
if(mark[x])return true;
mark[x]=true;
s[c++]=x;
for(int i=0;i<g[x].size();i++)
{
if(!dfs(g[x][i]))return false;
}
return true;
}
void init(int n)
{
this->n=n;
for(int i=0;i<n*2;i++)
g[i].clear();
memset(mark,0,sizeof(mark));
}
void add_clause(int x,int xval,int y,int yval)
{
x=x*2+xval;
y=y*2+yval;
g[x].push_back(y^1);
g[y].push_back(x^1);
}
bool solve()
{
for(int i=0;i<n*2;i+=2)
{
if(!mark[i]&&!mark[i+1])
{
c=0;
if(!dfs(i))
{
while(c>0)mark[s[--c]]=0;
if(!dfs(i+1))return false;
}
}
}
return true;
}
};

TwoSat solver;

const int maxm=10005;
int a[maxm],b[maxm],c[maxm];
int n,m;
int check(int k)
{
solver.init(n);
for(int i=0;i<k;i++)
{
if(c[i]==0)
{
int x=a[i],y=b[i];
solver.add_clause(x,0,y,0);
}
if(c[i]==2)
{
int x=a[i],y=b[i];
solver.add_clause(x,1,y,1);
}
if(c[i]==1)
{
int x=a[i],y=b[i];
solver.add_clause(x,0,y,1);
solver.add_clause(x,1,y,0);
}
}
return solver.solve();
}
int main()
{
int t;
scanf("%d",&t);
for(int ca=1;ca<=t;ca++)
{
scanf("%d%d",&n,&m);
for(int i=0;i<m;i++)
scanf("%d%d%d",&a[i],&b[i],&c[i]);
int l=0,r=m+1;
while(l<r)
{
int mid=(r+l)>>1;
if(check(mid))
l=mid+1;
else r=mid;
}
printf("%d\n",l-1);
}
return 0;
}

UVALive 5010 Go Deeper 2sat

时间: 2024-10-14 13:15:17

UVALive 5010 Go Deeper 2sat的相关文章

UVALive 3713 Astronauts (2-SAT,变形)

题意:有A,B,C三种任务,每个人必获得1个任务,大于等于平均年龄的可以选择A和C,小于平均年龄的可以选择B和C.这些人有一些是互相讨厌的,必须不能执行同任务,问能否安排他们工作?若行,输出任意一组解. 思路: 依然是 2-SAT,只不过换了个样子,建图时不同而已.这里每个人依然有2人选择,也有冲突的出现,问题在如何找出冲突. 首先,无论是哪两人,只要互相讨厌,去抢C,必定冲突.其次,如果是同龄人(同大于等于,或同小于),那么抢他们那个年龄段的任务也会冲突.所以共计2种,每种2条边,即我选的时候

2-SAT问题

2-SAT问题 现有一个由N个布尔值组成的序列A,给出一些限制关系,比如A[x]AND A[y]=0.A[x] OR A[y] OR A[z]=1等,要确定A[0..N-1]的值,使得其满足所有限制关系.这个称为SAT问题,特别的,若每种限制关系中最多只对两个元素进行限制,则称为2-SAT问题. 由于在2-SAT问题中,最多只对两个元素进行限制,所以可能的限制关系共有11种: A[x] NOT A[x] A[x] AND A[y] A[x] AND NOT A[y] A[x] OR A[y] A

补题列表

上海网络赛: HDU 5468 Puzzled Elena HDU 5469 Antonidas HDU 5473 There was a kingdom 合肥网络赛: HDU 5487 Difference of Languages HDU 5486 Difference of Clustering HDU 5489 Removed Interval HDU 5492 Find a path HDU 5493 Queue 弱校联萌Day1: B. Carries D. Vertex Cover

Go Deeper(2010成都现场赛题)(2-sat)

G - Go Deeper Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Description Here is a procedure's pseudocode: go(int dep, int n, int m) begin output the value of dep. if dep < m and x[a[dep]] + x[b[dep]] != c[dep] then go(dep +

HDU 3715 Go Deeper(2-sat)

HDU 3715 Go Deeper 题目链接 题意:根据题意那个函数,构造x数组,问最大能递归层数 思路:转化为2-sat问题,由于x只能是0,1,c只能是0,1,2那么问题就好办了,对于0, 1, 2对应分别是3种表达式,然后二分深度,搞2-sat即可 代码: #include <cstdio> #include <cstring> #include <cstdlib> #include <vector> #include <algorithm&g

UVALive - 4452 The Ministers&#39; Major Mess(2-SAT)

题目大意:有n个人对m个方案投票,每个人最多只能对其中的4个方案投票(其他的相当于弃权),每一票要么支持要么反对.问是否存在一个最终决定,使得每个投票人都有超过一半的建议被采纳,在所有可能的最终决定中,哪些方案的态度是确定的 解题思路:参考了一下别人的思路,学习了 当想要确定某一个状态(i)时,可以用他的相反状态(i^1)和该状态建立一条边,那样的话,每当dfs到他的相反状态时,就会return false 在理解了上面的基础上,就可以建边了 首先,要有超过一半的投票被采纳.也就是说,当投票数小

UVALive - 3211 (2-SAT + 二分)

layout: post title: 训练指南 UVALive - 3211 (2-SAT + 二分) author: "luowentaoaa" catalog: true mathjax: true tags: - 2-SAT - 图论 - 训练指南 Now or later UVALive - 3211 题意 n架飞机,每架可选择两个着落时间.安排一个着陆时间表,使得着陆间隔的最小值最大 题解 二分查找最大值P,每次都用2-SAT判断是否可行. #include<bits

UVALive - 3211 - Now or later(图论——2-SAT)

Problem   UVALive - 3211 - Now or later Time Limit: 9000 mSec Problem Description Input Output Sample Input 10 44 156 153 182 48 109 160 201 55 186 54 207 55 165 17 58 132 160 87 197 Sample Output 10 题解:2-SAT问题板子题,这个问题主要是理论难度比较大,有了结论之后代码很容易,有专门的论文阐释算

UVALive 4849 String Phone(2-sat、01染色)

题目一眼看去以为是4-sat... 题意:给n(n<=3000)个黑方块的坐标,保证黑方块没有公共边.对于每个黑方块选一个角作为结点,使得所选结点满足输入的一个无向图.其中距离为曼哈顿距离.输出是否有解.possible或impossible. 对于每个黑方块,4个角落必须选且仅选一个.一开始2-sat建模是对于一个pnt[i],有4对点pnt[i][0], pnt[i][0]', pnt[i][1], pnt[i][1]', pnt[i][2], pnt[i][2]', pnt[i][3],