看了大白书,学习了一下two-sat,很有意思的算法。题目就是大白书上的两题。

  仅仅放一下代码作为以后的模板参考。

 #include <stdio.h>
#include <algorithm>
#include <string.h>
#include <vector>
using namespace std;
const int N = + ; struct TwoSAT
{
int n;
vector<int> G[N*];
bool mark[N*];
int S[N*], c; bool dfs(int x)
{
if(mark[x^]) return ;
if(mark[x]) return ;
mark[x] = ;
S[c++] = x;
for(int i=;i<G[x].size();i++)
{
int v = G[x][i];
if(!dfs(v)) return false;
}
return true;
} void init(int n)
{
this->n = n;
for(int i=;i<*n;i++) G[i].clear();
memset(mark,false,sizeof(mark));
} void addEdge(int x,int xval,int y,int yval)
{
x = x * + xval;
y = y * + yval;
G[x^].push_back(y);
G[y^].push_back(x);
} bool solve()
{
for(int i=;i<*n;i+=)
{
if(!mark[i] && !mark[i+])
{
c = ;
if(!dfs(i))
{
while(c > ) mark[S[--c]] = ;
if(!dfs(i + )) return false;
}
}
}
return true;
}
}solver; int n;
int T[N][];
bool can(int dif)
{
solver.init(n);
for(int i=;i<n;i++) for(int j=i+;j<n;j++)
for(int a=;a<;a++) for(int b=;b<;b++)
{
if(std::abs(T[i][a] - T[j][b]) < dif) solver.addEdge(i,a^,j,b^);
}
return solver.solve();
} int main()
{
while(scanf("%d",&n) == )
{
int L = , R = ;
for(int i=;i<n;i++) for(int j=;j<;j++) {scanf("%d",&T[i][j]); R = max(R, T[i][j]);}
int ans = -;
while(L <= R)
{
int mid = L + R >> ;
if(can(mid)) {ans = mid; L = mid + ;}
else R = mid - ;
}
printf("%d\n",ans);
}
return ;
}

UVALive - 3211

 #include <stdio.h>
#include <algorithm>
#include <string.h>
#include <vector>
using namespace std;
const int N = 1e5 + ; struct TwoSAT
{
int n;
vector<int> G[N*];
bool mark[N*];
int S[N*], c; bool dfs(int x)
{
if(mark[x^]) return ;
if(mark[x]) return ;
mark[x] = ;
S[c++] = x;
for(int i=;i<G[x].size();i++)
{
int v = G[x][i];
if(!dfs(v)) return false;
}
return true;
} void init(int n)
{
this->n = n;
for(int i=;i<*n;i++) G[i].clear();
memset(mark,false,sizeof(mark));
} void addEdge(int x,int xval,int y,int yval)
{
x = x * + xval;
y = y * + yval;
G[x^].push_back(y);
G[y^].push_back(x);
} bool solve()
{
for(int i=;i<*n;i+=)
{
if(!mark[i] && !mark[i+])
{
c = ;
if(!dfs(i))
{
while(c > ) mark[S[--c]] = ;
if(!dfs(i + )) return false;
}
}
}
return true;
}
}solver; int n,m;
int p[N];
char get(bool mark,bool flag)
{
if(flag) return mark ? 'A' : 'C';
else return mark ? 'B' : 'C';
} int main()
{
while(scanf("%d%d",&n,&m) == )
{
if(n == && m == ) break;
solver.init(n);
int sum = ;
for(int i=;i<n;i++) scanf("%d",p+i), sum += p[i]; for(int i=;i<m;i++)
{
int a,b;
scanf("%d%d",&a,&b);
a--, b--;
if(n * p[a] >= sum && n * p[b] >= sum || n * p[a] < sum && n * p[b] < sum)
{
solver.addEdge(a,,b,);
solver.addEdge(a,,b,);
}
else solver.addEdge(a,,b,);
}
if(solver.solve() == false) puts("No solution.");
else
{
for(int i=;i<*n;i+=)
{
if(solver.mark[i]) puts("C");
else if(n * p[i / ] >= sum) puts("A");
else puts("B");
}
}
}
return ;
}

UVALive - 3713

2-SAT两题的更多相关文章

  1. MT【249】离心率两题

    椭圆$\dfrac{x^2}{a^2}+\dfrac{y^2}{b^2}=1,(a>b>0)$的一个焦点为$F$,过$F$的直线交椭圆于$A,B$两点,$M$是点$A$关于原点的对称点.若 ...

  2. 最近切的两题SCC的tarjan POJ1236 POJ2186

    两题都是水题,1236第一问求缩点后入度为0的点数,第二问即至少添加多少条边使全图强连通,属于经典做法,具体可以看白书 POJ2186即求缩点后出度为0的那个唯一的点所包含的点数(即SCC里有多少点) ...

  3. 清橙A1206.小Z的袜子 && CF 86D(莫队两题)

    清橙A1206.小Z的袜子 && CF 86D(莫队两题) 在网上看了一些别人写的关于莫队算法的介绍,我认为,莫队与其说是一种算法,不如说是一种思想,他通过先分块再排序来优化离线查询问 ...

  4. 类似区间计数的种类并查集两题--HDU 3038 & POJ 1733

    1.POJ 1733 Parity game Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 5744   Accepted: ...

  5. Codeforces Round #197 (Div. 2) C,D两题

    开了个小号做,C题一开始看错范围,D题看了半小时才看懂,居然也升到了div1,囧. C - Xenia and Weights 给出一串字符串,第i位如果是1的话,表示有重量为i的砝码,如果有该种砝码 ...

  6. Educational Codeforces Round 58 (Rated for Div. 2) (前两题题解)

    感慨 这次比较昏迷最近算法有点飘,都在玩pygame...做出第一题让人hack了,第二题还昏迷想错了 A Minimum Integer(数学) 水题,上来就能做出来但是让人hack成了tle,所以 ...

  7. noip2016 小结(ac两题+学习总结)

    NOIP2016考试小结 DAY 1 T1 题目描述 小南有一套可爱的玩具小人, 它们各有不同的职业. 有一天, 这些玩具小人把小南的眼镜藏了起来. 小南发现玩具小人们围成了一个圈,它们有的面朝圈内, ...

  8. <每日一题> Day5:简单递推两题

    原题链接 参考代码: #include <iostream> using namespace std; typedef long long ll; + ; ll dp[maxn]; int ...

  9. 【leetcode每日两题】-Day1-简单题

    1. 两数之和 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标. 你可以假设每种输入只会对应一个答案.但是,数组中同一个元素 ...

随机推荐

  1. java 框架-缓冲-Redis 2Jedis操作

    https://www.cnblogs.com/wlandwl/p/redis.html Redis介绍及Jedis基础操作   1.Redis简介 Redis 是一个开源(BSD许可)的,内存中的数 ...

  2. 听课笔记--DP--Authentication Failed

    Authentication Failed https://www.codechef.com/problems/AUTHEN/ 从一个长为N+K的由小写字母组成的字符串中删去K个字符, 可以得到多少种 ...

  3. Docker启动Elasticsearch报错java.nio.file.AccessDeniedException

    报错信息 Caused by: java.nio.file.AccessDeniedException: /usr/share/elasticsearch/data/nodes 问题分析 表面上是说容 ...

  4. java jdk1.8 API

    里面有 中英文 jdk 1.8 API    还有 jdk1.6 和1.7 英文 API 链接:https://pan.baidu.com/s/1tchABVX7htJCaO3quENP1g提取码:y ...

  5. C# 交换排序

    用交换排序的方式实现对int类型的数组arrays从小到大排序 思路: 第一步:一个长度为n的数组,把最小的放第一行,第二小的数字放第二行,,,, 0(0为数组的第一项) 第一小的数字 1      ...

  6. 面试题之String s="a"+"b"+"c"+"d";

    今天遇到了一个面试题的选择,我当时真的没怎么在意,其实挺好玩的. 1.这条语句String s="a"+"b"+"c"+"d&qu ...

  7. [Vuex系列] - 初尝Vuex第一个例子

    Vuex是什么? Vuex是一个专为vue.js应用程序开发的状态管理库.它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化. 通过定义和隔离状态管理中的各种概 ...

  8. liunx mkisofs 命令的使用(制作iso)

    参考的博客 http://www.cnblogs.com/darkknightzh/p/8564483.html 有很多时候需要在liunx 环境中将文件打成 iso 所有很多时候就会用到这个命令(m ...

  9. 2.Java集合-ConcurrentHashMap实现原理及源码分析

    一.为何用ConcurrentHashMap 在并发编程中使用HashMap可能会导致死循环,而使用线程安全的HashTable效率又低下. 线程不安全的HashMap 在多线程环境下,使用HashM ...

  10. flask小结

    http通讯过程 https://www.cnblogs.com/andy9468/p/10871079.html 1.flask开发环境 https://www.cnblogs.com/andy94 ...