图论--2-SAT--HDOJ/HDU 1824 Let's go home
Problem Description
小时候,乡愁是一枚小小的邮票,我在这头,母亲在那头。
—— 余光中
集训是辛苦的,道路是坎坷的,休息还是必须的。经过一段时间的训练,lcy决定让大家回家放松一下,但是训练还是得照常进行,lcy想出了如下回家规定,每一个队(三人一队)或者队长留下或者其余两名队员同时留下;每一对队员,如果队员A留下,则队员B必须回家休息下,或者B留下,A回家。由于今年集训队人数突破往年同期最高记录,管理难度相当大,lcy也不知道自己的决定是否可行,所以这个难题就交给你了,呵呵,好处嘛~,免费**漂流一日。
Input
第一行有两个整数,T和M,1<=T<=1000表示队伍数,1<=M<=5000表示对数。
接下来有T行,每行三个整数,表示一个队的队员编号,第一个队员就是该队队长。
然后有M行,每行两个整数,表示一对队员的编号。
每个队员只属于一个队。队员编号从0开始。
Output
可行输出yes,否则输出no,以EOF为结束。
Sample Input
1 2 0 1 2 0 1 1 2 2 4 0 1 2 3 4 5 0 3 0 4 1 3 1 4
Sample Output
yes no
(1)题目第一个条件:每一个队或者队长留下或者其与两名队员同时留下,或者表明只能为两种情况中的一种;假设三人为A,B,C,队长为A,0表示不留下,1表示留下,因为B与C同时留下或者不留下,只要B,C中其中一个没有留下或者留下,则B,C中另一个也同样留下或者不留下,所以可以从该条件中推导出六条等价关系,即A不留下->B,C同时留下,A留下->B,C同时不留下,B留下->C留下,A不留下,B留下->C留下,A不留下,C留下->B留下,A不留西,C不留下->B不留下,A留下;
(2)题目中第二个条件:每一对队员,如果队员A留下,则B必须回家休息,或者B留下,A必须回家休息;则可以推导出两条等价式:A留下->B不留下,B留下->A不留下,注意在这个条件中可以A,B都不留下;
AC代码:
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#include <stack>
#include <algorithm>
#include <iostream>
#define MAXN 7000+10
#define MAXM 400000
#define INF 1000000
using namespace std;
vector<int> G[MAXN];
int low[MAXN], dfn[MAXN];
int dfs_clock;
int sccno[MAXN], scc_cnt;
stack<int> S;
bool Instack[MAXN];
int N, M;
void init()
{
for(int i = 0; i <=6*N; i++) G[i].clear();
while(S.size()) S.pop();
dfs_clock=scc_cnt=0;
}
void getMap()
{
int a,b,c;
for(int i=0;i<N;i++)
{
scanf("%d %d %d",&a,&b,&c);
G[a+N*3].push_back(b);
G[a+N*3].push_back(c);
G[b+3*N].push_back(a);
G[c+3*N].push_back(a);
}
while(M--)
{
scanf("%d%d",&a,&b);
G[a].push_back(b+N*3);
G[b].push_back(a+N*3);
}
}
void tarjan(int u, int fa)
{
int v;
low[u] = dfn[u] = ++dfs_clock;
S.push(u);
Instack[u] = true;
for(int i = 0; i < G[u].size(); i++)
{
v = G[u][i];
if(!dfn[v])
{
tarjan(v, u);
low[u] = min(low[u], low[v]);
}
else if(Instack[v])
low[u] = min(low[u], dfn[v]);
}
if(low[u] == dfn[u])
{
scc_cnt++;
for(;;)
{
v = S.top(); S.pop();
Instack[v] = false;
sccno[v] = scc_cnt;
if(v == u) break;
}
}
}
void find_cut(int l, int r)
{
memset(low, 0, sizeof(low));
memset(dfn, 0, sizeof(dfn));
memset(sccno, 0, sizeof(sccno));
memset(Instack, false, sizeof(Instack));
dfs_clock = scc_cnt = 0;
for(int i = l; i <= r; i++)
if(!dfn[i]) tarjan(i, -1);
}
void solve()
{
for(int i = 0; i < 3*N; i++)
{
if(sccno[i] == sccno[i+3*N])//矛盾
{
printf("no\n");
return ;
}
}
printf("yes\n");
}
int main()
{
while(scanf("%d%d", &N, &M) != EOF)
{
init();
getMap();
find_cut(0, 6*N-1);
solve();
}
return 0;
}
图论--2-SAT--HDOJ/HDU 1824 Let's go home的更多相关文章
- HDU 3062 && HDU 1824 && POJ 3678 && BZOJ 1997 2-SAT
一条边<u,v>表示u选那么v一定被选. #include <iostream> #include <cstring> #include <cstdio> ...
- HDOJ(HDU).1412 {A} + {B} (STL SET)
HDOJ(HDU).1412 {A} + {B} (STL SET) 点我挑战题目 题意分析 大水题,会了set直接用set即可. 利用的是set的互异性(同一元素有且仅有一项). #include ...
- HDOJ(HDU).1754 I Hate It (ST 单点替换 区间最大值)
HDOJ(HDU).1754 I Hate It (ST 单点替换 区间最大值) 点我挑战题目 题意分析 从题目中可以看出是大数据的输入,和大量询问.基本操作有: 1.Q(i,j)代表求区间max(a ...
- HDOJ(HDU).1166 敌兵布阵 (ST 单点更新 区间求和)
HDOJ(HDU).1166 敌兵布阵 (ST 单点更新 区间求和) 点我挑战题目 题意分析 根据数据范围和询问次数的规模,应该不难看出是个数据结构题目,题目比较裸.题中包括以下命令: 1.Add(i ...
- HDOJ(HDU).2844 Coins (DP 多重背包+二进制优化)
HDOJ(HDU).2844 Coins (DP 多重背包+二进制优化) 题意分析 先把每种硬币按照二进制拆分好,然后做01背包即可.需要注意的是本题只需要求解可以凑出几种金钱的价格,而不需要输出种数 ...
- HDOJ(HDU).1059 Dividing(DP 多重背包+二进制优化)
HDOJ(HDU).1059 Dividing(DP 多重背包+二进制优化) 题意分析 给出一系列的石头的数量,然后问石头能否被平分成为价值相等的2份.首先可以确定的是如果石头的价值总和为奇数的话,那 ...
- HDOJ(HDU).2191. 悼念512汶川大地震遇难同胞――珍惜现在,感恩生活 (DP 多重背包+二进制优化)
HDOJ(HDU).2191. 悼念512汶川大地震遇难同胞――珍惜现在,感恩生活 (DP 多重背包+二进制优化) 题意分析 首先C表示测试数据的组数,然后给出经费的金额和大米的种类.接着是每袋大米的 ...
- HDOJ(HDU).2159 FATE (DP 带个数限制的完全背包)
HDOJ(HDU).2159 FATE (DP 带个数限制的完全背包) 题意分析 与普通的完全背包大同小异,区别就在于多了一个个数限制,那么在普通的完全背包的基础上,增加一维,表示个数.同时for循环 ...
- HDOJ(HDU).4508 湫湫系列故事――减肥记I (DP 完全背包)
HDOJ(HDU).4508 湫湫系列故事――减肥记I (DP 完全背包) 题意分析 裸完全背包 代码总览 #include <iostream> #include <cstdio& ...
- HDOJ(HDU).1284 钱币兑换问题 (DP 完全背包)
HDOJ(HDU).1284 钱币兑换问题 (DP 完全背包) 题意分析 裸的完全背包问题 代码总览 #include <iostream> #include <cstdio> ...
随机推荐
- 《深入理解 Java 虚拟机》笔记整理
正文 一.Java 内存区域与内存溢出异常 1.运行时数据区域 程序计数器:当前线程所执行的字节码的行号指示器.线程私有. Java 虚拟机栈:Java 方法执行的内存模型.线程私有. 本地方法栈:N ...
- excel完成数据库数据的批量插入
业务场景: 开发过程中往往会遇到这样情况就是产品直接给我们一堆数据,让咱们直接导入到后台数据库中,这时候咱们只需要在excel表中进行直接操作即可,如图所示(以河北省的编号为例): 而对应的数据表为: ...
- layoutInflater参数解析与源码分析
关于LayoutInflater方法,无论是在listview的适配器中,还是在动态添加view的时候,都会出现它的身影,最开始我在看<第一行代码>时,不知道这个方法实际的参数到底指的是什 ...
- 通过神秘代码登录自己的QQ
通过神秘代码登录自己的QQ 如图:是怎么做成的呢? 其实很明显,这个是QQ号码的16进制 所以网上搜索进制转换打开一个网页 输入自己的QQ号码,得到16进制的QQ号码 在QQ页面账号处先添加0x然后复 ...
- Linux-设备-磁盘
磁盘的每个扇区为512bytes.磁盘的第一个扇区记录了整块磁盘的重要信息,包含有主引导分区(MBR):可以安装引导加载程序的地方,有446bytes:分区表(partition table):记录整 ...
- harbor仓库搭建
harbor安装要求 harbor快速部署 下载harbor:https://github.com/goharbor/harbor/releases 这边以harbor-1.8.2为例 [root@g ...
- .Net Core主机配置
Host:(主机)负责web应用程序的启用和生成期管理,配置服务器和请求处理管道. 主机配置日志,依赖注入关系,实际上是一个封装了应用资源的对象. 创建主机生成器-〉配置主机-〉创建主机-〉运行主机. ...
- Nginx知多少系列之(十四)Linux下.NET Core项目Nginx+Keepalived高可用(主从模式)
目录 1.前言 2.安装 3.配置文件详解 4.工作原理 5.Linux下托管.NET Core项目 6.Linux下.NET Core项目负载均衡 7.负载均衡策略 8.加权轮询(round rob ...
- php-fpm运行原理
来源:https://blog.csdn.net/sinat_38804294/article/details/94393621 一.php-fpm由来1.cgi (common gateway in ...
- IntelliJ IDEA在mac中完全删除方法
cd /Applications/ rm -r IntelliJ\ IDEA.app/ rm -r /Users/apple/Library/Logs/IntelliJIdea2019.3/ rm - ...