hdu1824-Let's go home:图论2-SAT

关键在于找出一定矛盾的条件,设一队的3个人为(a,b,c),a为队长,那么(a不留下,b不留下)矛盾,(a不留下,c不留下)矛盾; 对于每一对队员,(a留下,b留下)矛盾。

把模型建好,剩下的就是套模板了。


 1 #include<cstdio>
 2 #include<vector>
 3 #include<cstring>
 4 using namespace std;
 5
 6 const int maxn = 3000+10;
 7
 8 struct TwoSAT
 9 {
10     int n;
11     vector<int> G[maxn*2];
12     bool mark[maxn*2];
13     int S[maxn*2], c;
14
15     bool dfs(int x)
16     {
17         if (mark[x^1]) return false;
18         if (mark[x]) return true;
19         mark[x] = true;
20         S[c++] = x;
21         for (int i = 0; i < G[x].size(); i++)
22             if (!dfs(G[x][i])) return false;
23         return true;
24     }
25
26     void init(int n)
27     {
28         this->n = n;
29         for (int i = 0; i < n*2; i++) G[i].clear();
30         memset(mark, 0, sizeof(mark));
31     }
32
33     // x = xval or y = yval
34     void add_clause(int x, int xval, int y, int yval)
35     {
36         x = x * 2 + xval;
37         y = y * 2 + yval;
38         G[x^1].push_back(y);
39         G[y^1].push_back(x);
40     }
41
42     bool solve()
43     {
44         for(int i = 0; i < n*2; i += 2)
45             if(!mark[i] && !mark[i+1])
46             {
47                 c = 0;
48                 if(!dfs(i))
49                 {
50                     while(c > 0) mark[S[--c]] = false;
51                     if(!dfs(i+1)) return false;
52                 }
53             }
54         return true;
55     }
56 };
57
58
59 ///////////////////////////////////////////////////////////////
60 #include <iostream>
61 #include <cmath>
62 using namespace std;
63 TwoSAT solver;
64
65 int main()
66 {
67     int t,m;
68     while(~scanf("%d%d",&t,&m))
69     {
70         solver.init(t*3);
71         for(int i=0;i<t;i++)
72         {
73             int a,b,c;
74             scanf("%d%d%d",&a,&b,&c);
75             solver.add_clause(a,0,b,0); // 0表示不留下,1表示留下
76             solver.add_clause(a,0,c,0);
77             //solver.add_clause(b,1,c,0);
78             //solver.add_clause(c,1,b,0);
79         }
80
81         for(int i=0;i<m;i++)
82         {
83             int a,b;
84             scanf("%d %d",&a,&b);
85             solver.add_clause(a,1,b,1);
86         }
87         printf("%s\n",solver.solve()?"yes":"no");
88     }
89     return 0;
90 }

hdu1824-Let's go home:图论2-SAT

时间: 2024-08-09 11:33:33

hdu1824-Let's go home:图论2-SAT的相关文章

第九节 图论和搜索

1. 图论算法(用BFS,DFS) 拓扑排序 克隆图 找连通块 六度问题 2.BFS 队列实现:    树中的BFS与图中的BFS有什么不同?树中没有环,图中有环需要一个set来记录搜索过的节点: 应用:图的遍历,最短路径 3 搜索   搜索题的套路比较固定.

图论(A*算法,K短路) :POJ 2449 Remmarguts&#39; Date

Remmarguts' Date Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 25216   Accepted: 6882 Description "Good man never makes girls wait or breaks an appointment!" said the mandarin duck father. Softly touching his little ducks' head, h

ACM 图论入门

①图论基础 图由点和边组成 记顶点集合为V 边集合为E的图为G=(V,E) 图可分为有向图和无向图.如表示朋友关系的图为无向图,表示点之间大小关系的图为有向图. 边也可以带有权值,带有权值称为有权图,不带有权值称为 无权图. 一.关于无向图 任意两点之间都有路径的图叫做连通图,顶点连接的边数称为这个点的度. 没有环的连通图就是树,没有环的非连通图就是森林. 一棵树的边数=顶点数-1.反之 边数=顶点数-1的连通图就是树. 二.关于有向图 以一个点为起点的边数称作这个点的出度,以一个点为终点的边数

Codeforces 444A DZY Loves Physics(图论)

题目链接:Codeforces 444A DZY Loves Physics 题目大意:给出一张图,图中的每个节点,每条边都有一个权值,现在有从中挑出一张子图,要求子图联通,并且被选中的任意两点,如果存在边,则一定要被选中.问说点的权值和/边的权值和最大是多少. 解题思路:是图论中的一个结论,最多两个节点,所以枚举两条边就可以了.我简单的推了一下,2个点的情况肯定比3个点的优. 假设有3个点a,b,c,权值分别为A,B,C 现a-b,b-c边的权值分别为u,v 那么对于两点的情况有A+Bu,B+

图论算法之DFS与BFS

概述(总) DFS是算法中图论部分中最基本的算法之一.对于算法入门者而言,这是一个必须掌握的基本算法.它的算法思想可以运用在很多地方,利用它可以解决很多实际问题,但是深入掌握其原理是我们灵活运用它的关键所在. 含义特点 DFS即深度优先搜索,有点类似广度优先搜索,也是对一个连通图进行遍历的算法.它的思想是从一个顶点V0开始,沿着一条路一直走到底,如果发现不能到达目标解,那就返回到上一个节点,然后从另一条路开始走到底,这种尽量往深处走的概念即是深度优先的概念. 由于用到递归,当节点特别多且深度很大

codevs——1019 集合论与图论

1019 集合论与图论 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题解 查看运行结果 题目描述 Description 集合论与图论对于小松来说是比数字逻辑轻松,比数据结构难的一门专业必修课.虽然小松在高中的时候已经自学过了离散数学中的图论,组合,群论等知识.但对于集合论,小松还是比较陌生的.集合论的好多东西也涉及到了图论的知识. 在第四讲的学习中,小松学到了“有序对”这么一个概念,即用<x, y>表示有序对x和y.要注意的是有序对<x, y>

关于图论的若干巴拉巴拉

最近课堂上正在讲图论 先安利MIT课程:http://open.163.com/special/opencourse/algorithms.html 因为本人对图论的概念并不是很清楚,所以还是整理一下吧. 1.图论的基本概念 几种常见的图的分类: 类型 边 允许多重边 允许环 简单图 无向 否 否 多重图 无向 是 否 伪图 无向 是 是 有向图 有向 否 是 有向多重图 有向 是 是 完全图:n个顶点上的完全图是在每对不同顶点之间都恰有一条边的简单图. 二分图:若把简单图G的顶点集合分为两个不

cdoj1580 简单图论问题

地址:http://acm.uestc.edu.cn/#/problem/show/1580 题目: 简单图论问题 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit Status 给出一个无向图,该图由nn个点和mm条边组成,每个点和每条边都有一个权值.对于该图的任意一个子图,我们定义A是该子图的点权和,B是该子图的边权和,C=A/b=AB是该子图的powerpow

LA 3211 飞机调度(2—SAT)

https://vjudge.net/problem/UVALive-3211 题意: 有n架飞机需要着陆,每架飞机都可以选择“早着陆”和“晚着陆”两种方式之一,且必须选择一种,第i架飞机的早着陆时间为E,晚着陆时间为L,不得在其他时间着陆.你的任务是为这些飞机安排着陆方式,使得整个着陆计划尽量安全.换句话说,如果把所有飞机的实际着陆时间按照从早到晚的顺序排列,相邻两个着陆时间间隔的最小值. 思路: 二分查找最大值P,每次都用2—SAT判断是否可行. 1 #include<iostream>

SDUT 3361 数据结构实验之图论四:迷宫探索

数据结构实验之图论四:迷宫探索 Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic Discuss Problem Description 有一个地下迷宫,它的通道都是直的,而通道所有交叉点(包括通道的端点)上都有一盏灯和一个开关:请问如何从某个起点开始在迷宫中点亮所有的灯并回到起点? Input 连续T组数据输入,每组数据第一行给出三个正整数,分别表示地下迷宫的结点数N(1 < N <= 1000).边数M(M <= 30