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 ...
随机推荐
- 简单几行代码使用百度地图API接口分页获取信息
首发于: 万能助手扩展开发:使用百度地图API接口分页获取信息_电脑计算机编程入门教程自学 http://jianma123.com/viewthread.aardio?threadid=426 使用 ...
- 第一个electron
1 开发环境:node环境 2 下载electron:npm install electron --save-dev 3 package.json配置如下: { "name": & ...
- 如何创建systemd定时任务
1. 如何创建一个定时任务,通过systemd系统 1. 如何创建一个定时任务,通过systemd系统 1.1. systemd中的timer 1.2. 自定义定时任务 1.2.1. 具体步骤 1.2 ...
- phpstudy lamp
phpStudy for Linux (lnmp+lamp一键安装包 现在不考虑安装这个 (完整版:http://lamp.phpstudy.net/phpstudy-all.bin) 安装: wg ...
- 如何在 EXCEL 2003 插入的方框内打对勾,复选框
一个方框里带勾的符号是吧第一种:EXCEL里有个插入符号的功能知道吧,打开它在符号那栏(不是特殊符号那栏),下拉字体找到Wingdings字体,在下面的符号中就能找到框中带勾的符号 第二种:在界面点& ...
- Delphi采用接口实现DLL调用
Delphi使用模块化开发,可以采用DLL或者BPL,两者的区别是BPL只能被同版本的Delphi使用,DLL可以被不同版本和不同开发工具的开发的软件调用. 因此我们的软件大多使用Delphi作为界面 ...
- Linux字符设备学习,总结
注册字符驱动的一种老方法: 注册一个字符设备的经典方法是使用:int register_chrdev(unsigned int major, const char *name, structfile_ ...
- stylus , another css processor
1. install from npm sudo npm install stylus 2. create a styl file named step1.styl border-radius() { ...
- 6、Java并发编程:volatile关键字解析
Java并发编程:volatile关键字解析 volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果.在 ...
- 笔记:ndk-stack和addr2line
笔记:关于ndk开发调试时,获取崩溃堆栈方法 1. 使用ndk-stack 直接获取c/c++崩溃代码的文件名和行号 adb shell logcat | ndk-stack -sym $PROJEC ...