Codeforces Round #347 (Div. 2) D. Graph Coloring(强联通分量缩点+2-SAT)
2016-09-16 18:08
323 查看
题意:
给你n个点m条边,每条边有一种颜色(B或R),每选择一个点可以使与其相连的所有边的颜色翻转,问最少需要选择多少个点,使得所有边的颜色相同,输出操作数以及操作哪些点。
(1 ≤ n,m ≤ 100000)
思路:
我们可以分别对把所有边变成B和R分别考虑。
因为每个点不会操作2次或者更多,因为操作两次相当于不操作,操作三次相当于操作一次。
然后用2-sat强连通模板跑
假设现在要把所有边变成R,现在有u,v两点之间的边为B,
我们用v+n,u+n表示这两个点不翻转,u,v表示这两个点进行翻转
则我们可以建立以下四条边
u->v+n,v+n->u,u+n->v,v->u+n
由于是有向图,所以tarjan不需要判断父亲
给你n个点m条边,每条边有一种颜色(B或R),每选择一个点可以使与其相连的所有边的颜色翻转,问最少需要选择多少个点,使得所有边的颜色相同,输出操作数以及操作哪些点。
(1 ≤ n,m ≤ 100000)
思路:
我们可以分别对把所有边变成B和R分别考虑。
因为每个点不会操作2次或者更多,因为操作两次相当于不操作,操作三次相当于操作一次。
然后用2-sat强连通模板跑
假设现在要把所有边变成R,现在有u,v两点之间的边为B,
我们用v+n,u+n表示这两个点不翻转,u,v表示这两个点进行翻转
则我们可以建立以下四条边
u->v+n,v+n->u,u+n->v,v->u+n
由于是有向图,所以tarjan不需要判断父亲
</pre><pre name="code" class="cpp">#include <set> #include <map> #include <stack> #include <queue> #include <deque> #include <cmath> #include <vector> #include <string> #include <cstdio> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define L(i) i<<1 #define R(i) i<<1|1 #define INF 0x3f3f3f3f #define pi acos(-1.0) #define eps 1e-12 #define maxn 200100 #define MOD 1000000007 struct Edge { int to,next; } edge[maxn<<1]; int n,m,ans; int tot,head[maxn],scc; int dfn[maxn],low[maxn],time; int sta[maxn],top,instack[maxn],vis[maxn]; int belong[maxn],num[maxn],flag[maxn]; vector<pair<int,int> > mp[maxn]; vector<int> tmp[maxn]; void init() { tot = 0; memset(head,-1,sizeof(head)); } void add_edge(int u,int v) { edge[tot].to = v; edge[tot].next = head[u]; head[u] = tot++; } void tarjan(int u) { dfn[u] = low[u] = ++time; sta[++top] = u; instack[u] = 1; for(int i = head[u]; i != -1; i = edge[i].next) { int v = edge[i].to; if(!dfn[v]) { tarjan(v); low[u] = min(low[u],low[v]); } else if(instack[v]) low[u] = min(low[u],dfn[v]); } if(dfn[u] == low[u]) { num[++scc] = 0; tmp[scc].clear(); while(1) { int v = sta[top--]; instack[v] = 0; belong[v] = scc; if(v <= n) num[scc]++; tmp[scc].push_back(v); if(v == u) break; } } } void solve(int key) { init(); for(int u = 1; u <= n; u++) { for(int i = 0; i < mp[u].size(); i++) { int v = mp[u][i].first; int c = mp[u][i].second; if(c == key) { add_edge(u,v); add_edge(u+n,v+n); } else { add_edge(u,v+n); add_edge(u+n,v); } } } top = time = scc = 0; memset(dfn,0,sizeof(dfn)); memset(instack,0,sizeof(instack)); memset(flag,0,sizeof(flag)); for(int i = 1; i <= 2*n; i++) if(!dfn[i]) tarjan(i); for(int i = 1; i <= n; i++) if(belong[i] == belong[i+n]) return; int cnt = 0; for(int i = 1; i <= n; i++) { if(flag[i]) continue; int k; if(num[belong[i]] <= num[belong[i+n]]) k = i; else k = i + n; cnt += num[belong[k]]; for(int j = 0; j < tmp[belong[k]].size(); j++) { int v = tmp[belong[k]][j]; flag[v] = 1; flag[v<=n?v+n:v-n] = 2; } } if(cnt < ans) { memset(vis,0,sizeof(vis)); ans = cnt; for(int i = 1; i <= n; i++) if(flag[i] == 1) vis[i] = 1; } } int main() { int t; while(scanf("%d%d",&n,&m) != EOF) { for(int i = 1; i <= n; i++) mp[i].clear(); for(int i = 0; i < m; i++) { int u,v; char c; scanf("%d%d %c",&u,&v,&c); mp[u].push_back(make_pair(v,c=='B'?1:2)); mp[v].push_back(make_pair(u,c=='B'?1:2)); } ans = INF; solve(1); solve(2); if(ans == INF) printf("-1\n"); else { printf("%d\n",ans); for(int i = 1; i <= n; i++) if(vis[i]) printf("%d ",i); printf("\n"); } } return 0; }
相关文章推荐
- POJ 2553 The Bottom of a Graph 缩点之后求出度为0的强联通分量的元素
- POJ3177 Redundant Paths —— 边双联通分量 + 缩点
- 【强联通分量缩点】【搜索】bzoj2208 [Jsoi2010]连通数
- [HAOI2006 受欢迎的牛] 强联通分量 缩点
- poj3177—Redundant Paths(缩点+边双联通分量)
- lightoj 1168 tarjan 强联通分量加缩点 加各种题目坑
- HDOJ 3861 - The King’s Problem tarjan求强联通分量&缩点&有向图最小路径覆盖(匈牙利)
- zoj 3232 It's not Floyd Algorithm(强联通分量,缩点)
- 【强联通分量缩点】【最长路】【spfa】CH Round #59 - OrzCC杯NOIP模拟赛day1 队爷的讲学计划
- HDOJ 1827 - Summer Holiday 简单的tarjan求强联通分量+缩点
- HDU5409---CRB and Graph 2015多校 双联通分量缩点
- Codeforces Round #347 (Div. 2) D. Graph Coloring(最少需要选择多少个点,使得所有边的颜色相同)
- ZOJ 3795 Grouping(强联通分量 + 缩点 + Dp)
- 文章标题 POJ 1236 : Network of Schools (强联通分量+缩点)
- 【最小割】【Dinic】【强联通分量缩点】bzoj1797 [Ahoi2009]Mincut 最小割
- 2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛 F.islands (强联通分量 + 缩点)
- POJ 1236 Network of Schools ★(经典问题:强联通分量+缩点)
- BZOJ 2438 杀人游戏 强联通分量tarjan缩点
- poj 2553 zoj 1979 The Bottom of a Graph(强联通分量 Tarjan)
- sdut 2604 Thrall’s Dream (强联通分量+缩点)