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 ...
随机推荐
- 竞赛题解 - CF Round #524 Div.2
CF Round #524 Div.2 - 竞赛题解 不容易CF有一场下午的比赛,开心的和一个神犇一起报了名 被虐爆--前两题水过去,第三题卡了好久,第四题毫无头绪QwQ Codeforces 传送门 ...
- 万恶的a标签
相信很多人碰见过这些问题吧 给某个a标签套的元素中添加点击事件 在外面就能获取到但是点击事件不生效把 或者在页面中点击一个a标签元素发现页面返回了最顶端 然后就开始郁闷了 哈哈 其实这些看似神奇的 ...
- php_Trait
* Trait Answer* Trait : 关键字 Trait* 使用 use* 我的理解 是为了解决php不能多继承的一个处理方式* 在使用的时候 可以让两个不相关的类 产生联系* Trait ...
- 基于C语言的面向对象编程
嵌入式软件开发中,虽然很多的开发工具已经支持C++的开发,但是因为有时考虑运行效率和编程习惯,还是有很多人喜欢用C来开发嵌入式软件.Miro Samek说:"我在开发现场发现,很多嵌入式软件 ...
- python3 安装pyhanlp方法
直接pip install pyhanlp的时候会提示缺少Microsoft Visual c++环境, 其实没有Microsoft Visual c++环境也是可以的, 可以先安装jpype1,然后 ...
- Python-变量与基础数据类型
·变量(variable) 笔记: 变量本质上是一个占位符.变量可以用来存储整数.字符串.列表等.简单的可以理解为一个座位,可以坐老人也可以坐小孩,可以坐男孩,也可以坐女孩. 在python里,标识 ...
- 推荐软件7 taskbar numberer,结果get了WIN相关的快捷键
作为键盘控,Win+数字直达任务栏上的应用已经让我欣喜.接下来我的问题就是每次要数数字才能确定是哪个数字,期间我尝试过按常用顺序进行排序并尝试记住它们.直到我想也许应该有个软件可以在任务栏图标处贴上一 ...
- 【转】Odoo:基本字段类型
class Stage(models.Model): _name = 'todo.task.stage' _order = 'sequence,name' # String fields: name ...
- 北京Uber优步司机奖励政策(3月14日)
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...
- ORB-SLAM(九)LocalMapping
LocalMapping作用是将Tracking中送来的关键帧放在mlNewKeyFrame列表中:处理新关键帧,地图点检查剔除,生成新地图点,Local BA,关键帧剔除.主要工作在于维护局部地图, ...