codeforces 228E The Road to Berland is Paved With Good Intentions(2-SAT)
Berland has n cities, some of them are connected by bidirectional roads. For each road we know whether it is asphalted or not.
The King of Berland Valera II wants to asphalt all roads of Berland, for that he gathered a group of workers. Every day Valera chooses exactly one city and orders the crew to asphalt all roads that come from the city. The valiant crew fulfilled the King's order in a day, then workers went home.
Unfortunately, not everything is as great as Valera II would like. The main part of the group were gastarbeiters — illegal immigrants who are enthusiastic but not exactly good at understanding orders in Berlandian. Therefore, having received orders to asphalt the roads coming from some of the city, the group asphalted all non-asphalted roads coming from the city, and vice versa, took the asphalt from the roads that had it.
Upon learning of this progress, Valera II was very upset, but since it was too late to change anything, he asked you to make a program that determines whether you can in some way asphalt Berlandian roads in at most n days. Help the king.
The first line contains two space-separated integers n, m — the number of cities and roads in Berland, correspondingly. Next m lines contain the descriptions of roads in Berland: the i-th line contains three space-separated integersai, bi, ci (1 ≤ ai, bi ≤ n; ai ≠ bi; 0 ≤ ci ≤ 1). The first two integers (ai, bi) are indexes of the cities that are connected by the i-th road, the third integer (ci) equals 1, if the road was initially asphalted, and 0 otherwise.
Consider the cities in Berland indexed from 1 to n, and the roads indexed from 1 to m. It is guaranteed that between two Berlandian cities there is not more than one road.
In the first line print a single integer x (0 ≤ x ≤ n) — the number of days needed to asphalt all roads. In the second line print x space-separated integers — the indexes of the cities to send the workers to. Print the cities in the order, in which Valera send the workers to asphalt roads. If there are multiple solutions, print any of them.
If there's no way to asphalt all roads, print "Impossible" (without the quotes).
题目大意:给一幅无向图,每条边有一个权值0或1,每选择一个点,这个点周围的边权就异或1,问能不能选择一些点,能把所有边权变成1,能则输出方案,不能则输出Impossible。
思路:2-SAT,边权为1边的两个点,只能同时选或同时不选,选和不选冲突,连边。边权为0的边的两个点,要选且只能选一个,选和选冲突,不选和不选冲突,连边。
代码(30MS):
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
using namespace std; const int MAXN = ;
const int MAXV = ;
const int MAXE = MAXV * MAXV; struct Topological {
int stk[MAXV], top;
int n, ecnt, cnt;
int head[MAXV], order[MAXV], indeg[MAXV];
int to[MAXE], next[MAXE]; void init(int nn) {
memset(head, -, sizeof(head));
memset(indeg, , sizeof(indeg));
n = nn; ecnt = ;
} void add_edge(int u, int v) {
to[ecnt] = v; next[ecnt] = head[u]; head[u] = ecnt++;
++indeg[v];
} void build() {
top = cnt = ;
for(int i = ; i <= n; ++i)
if(indeg[i] == ) stk[++top] = i;
while(top) {
int u = stk[top--]; order[cnt++] = u;
for(int p = head[u]; ~p; p = next[p]) {
int &v = to[p];
if(--indeg[v] == ) stk[++top] = v;
}
}
}
} T; struct TwoSAT {//从0开始编号
int stk[MAXV], top;
int n, ecnt, dfs_clock, scc_cnt;
int head[MAXV], sccno[MAXV], pre[MAXV], lowlink[MAXV];
int to[MAXE], next[MAXE];
int select[MAXV], sccnox[MAXV]; void init(int nn) {
memset(head, -, sizeof(head));
memset(pre, , sizeof(pre));
memset(sccno, , sizeof(sccno));
n = nn, ecnt = dfs_clock = scc_cnt = ;
} void add_edge(int x, int y) {//x, y clash
to[ecnt] = y ^ ; next[ecnt] = head[x]; head[x] = ecnt++;
to[ecnt] = x ^ ; next[ecnt] = head[y]; head[y] = ecnt++;
} void dfs(int u) {
lowlink[u] = pre[u] = ++dfs_clock;
stk[++top] = u;
for(int p = head[u]; ~p; p = next[p]) {
int &v = to[p];
if(!pre[v]) {
dfs(v);
if(lowlink[v] < lowlink[u]) lowlink[u] = lowlink[v];
} else if(!sccno[v]) {
if(pre[v] < lowlink[u]) lowlink[u] = pre[v];
}
}
if(lowlink[u] == pre[u]) {
sccnox[++scc_cnt] = u;
while(true) {
int x = stk[top--];
sccno[x] = scc_cnt;
if(x == u) break;
}
}
} bool solve() {
for(int i = ; i < n; ++i) if(!pre[i]) dfs(i);
for(int i = ; i < n; i += )
if(sccno[i] == sccno[i ^ ]) return false;
return true;
} void build_select() {
T.init(scc_cnt);
for(int u = ; u < n; ++u) {
for(int p = head[u]; ~p; p = next[p]) {
int &v = to[p];
if(sccno[u] == sccno[v]) continue;
T.add_edge(sccno[u], sccno[v]);
}
}
T.build();
memset(select, -, sizeof(select));
for(int i = T.n - ; i >= ; --i) {
int &x = T.order[i];
if(select[x] == -) {
select[x] = ;
select[sccno[sccnox[x] ^ ]] = ;
}
}
}
} G; int n, m; int main() {
scanf("%d%d", &n, &m);
G.init(n << );
for(int i = ; i < m; ++i) {
int u, v, p;
scanf("%d%d%d", &u, &v, &p);
--u, --v;
if(p) {
G.add_edge( * u, * v ^ );
G.add_edge( * u ^ , * v);
} else {
G.add_edge( * u, * v);
G.add_edge( * u ^ , * v ^ );
}
}
if(!G.solve()) {
printf("Impossible");
} else {
G.build_select();
int cnt = ;
for(int i = ; i < n; ++i) cnt += G.select[G.sccno[ * i]];
printf("%d\n", cnt);
for(int i = ; i < n; ++i)
if(G.select[G.sccno[ * i]]) printf("%d ", i + );
}
}
codeforces 228E The Road to Berland is Paved With Good Intentions(2-SAT)的更多相关文章
- Educational Codeforces Round 48 (Rated for Div. 2) B 1016B Segment Occurrences (前缀和)
B. Segment Occurrences time limit per test 2 seconds memory limit per test 256 megabytes input stand ...
- codeforces 741D Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths(启发式合并)
codeforces 741D Arpa's letter-marked tree and Mehrdad's Dokhtar-kosh paths 题意 给出一棵树,每条边上有一个字符,字符集大小只 ...
- Educational Codeforces Round 47 (Rated for Div. 2) :C. Annoying Present(等差求和)
题目链接:http://codeforces.com/contest/1009/problem/C 解题心得: 题意就是一个初始全为0长度为n的数列,m此操作,每次给你两个数x.d,你需要在数列中选一 ...
- Codeforces Round #286 (Div. 1) B. Mr. Kitayuta's Technology (强连通分量)
题目地址:http://codeforces.com/contest/506/problem/B 先用强连通判环.然后转化成无向图,找无向图连通块.若一个有n个点的块内有强连通环,那么须要n条边.即正 ...
- Educational Codeforces Round 89 (Rated for Div. 2) A. Shovels and Swords(贪心/数学)
题目链接:https://codeforces.com/contest/1366/problem/A 题意 有两个数 $a$ 和 $b$,每次可以选择从一个数中取 $2$,另一个数中取 $1$,问最多 ...
- Codeforces Round #259 (Div. 2) C - Little Pony and Expected Maximum (数学期望)
题目链接 题意 : 一个m面的骰子,掷n次,问得到最大值的期望. 思路 : 数学期望,离散时的公式是E(X) = X1*p(X1) + X2*p(X2) + …… + Xn*p(Xn) p(xi)的是 ...
- codeforces 700C Break Up 暴力枚举边+边双缩点(有重边)
题意:n个点,m条无向边,每个边有权值,给你 s 和 t,问你至多删除两条边,让s,t不连通,问方案的权值和最小为多少,并且输出删的边 分析:n<=1000,m是30000 s,t有4种情况( ...
- Codeforces Round #496 (Div. 3 ) E1. Median on Segments (Permutations Edition)(中位数计数)
E1. Median on Segments (Permutations Edition) time limit per test 3 seconds memory limit per test 25 ...
- Codeforces Round #294 (Div. 2) A and B and Lecture Rooms(LCA 倍增)
A and B and Lecture Rooms time limit per test 2 seconds memory limit per test 256 megabytes input st ...
随机推荐
- 『C++』Temp_2018_12_13_Type
#include <iostream> #include <string> using namespace std; class Object{ public: virtual ...
- UIPickerView的简单使用
UIPickerView是一个选择器它可以生成单列的选择器,也可生成多列的选择器,而且开发者完全可以自定义选择项的外观,因此用法非常灵活,使用也比较简单.下面做了一个关于天气预报的小Demo 用 UI ...
- [翻译]Hystrix wiki–How it Works
注:本文并非是精确的文档翻译,而是根据自己理解的整理,有些内容可能由于理解偏差翻译有误,有些内容由于是显而易见的,并没有翻译,而是略去了.本文更多是学习过程的产出,请尽量参考原官方文档. 流程图 下图 ...
- 【JavaWeb】从零实现用户登录
1.数据库预备 1.1 SQL 创建数据库 create database db; 创建表 create table userInfo( id int primary key , name ), pa ...
- git 完善使用中
GIT 版本库控制: 第一步:Git 的账号注册 url :https://github.com/ 这是git的官网如果第一次打开会这样 中间红色圈内是注册 内容, 第一项是用户名 第二项是邮箱 第三 ...
- CI框架视图继承
CI(CodeIgniter)框架 视图继承 这个代码不是我撸的 ... 当时在哪儿找的忘了 ... 如果有侵权什么的 ... 联系我删了 ... 需要去core里面创建一个MY_loader.php ...
- php 冒泡法 排序
<?php /** * php 冒泡法 * @param $arr * @param string $order 排序符 * @return $arr */ function orderarr( ...
- Ubuntu中 MySQL 的中文编码问题
使用Ubuntu在安装好MySQL数据库之后,如果直接创建数据库,再创建数据表,那么是无法向字段插入中文的,会报Incorrect string value错误. c实现编码设置的两种方法: (1)动 ...
- python 自定义函数表达式 拟合求系数
https://docs.scipy.org/doc/scipy/reference/tutorial/integrate.html https://docs.scipy.org/doc/scipy/ ...
- 笔记-sql语句
笔记-sql语句 1. sql语句基础 虽然经常使用sql语句,但没有一个整体式的文档,整理了一下. 1.1. select foundation: select <colnum ...