zoukankan      html  css  js  c++  java
  • Codeforces Gym100502A:Amanda Lounges(DFS染色)

    http://codeforces.com/gym/100502/attachments

    题意:有n个地点,m条边,每条边有一个边权,0代表两个顶点都染成白色,2代表两个顶点都染成黑色,1代表两个顶点可能尚未染色,但是之后必须一个染成白色一个染成黑色。问是否有可能让这个图成功染色,如果可能输出染成黑色的最少顶点数。

    思路:一开始0和2的边是确定的,直接染,如果有矛盾直接false。然后利用边权为1的边建图。先考虑如果图中的某个点已经染色了,那么直接DFS染色,然后这个阶段出现黑色的点是确定的(因为必须染成这个颜色),如果出现矛盾就返回。

    再考虑如果图中没有点染色,这个时候随便染一种颜色,用两个计数器a和b,代表这个阶段染成白色的点和黑色的点的数目,这个对答案的贡献为min(a, b),因为点都是不确定的,所以染成白和染成黑都是一样的,所以可以互换,然后出现矛盾就返回。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 #define N 200010
     4 struct Edge {
     5     int v, nxt;
     6 } edge[N*2];
     7 int vis[N], head[N], tot, col[N], a, b, ans;
     8 
     9 void Add(int u, int v) {
    10     edge[tot] = (Edge) {v, head[u]}; head[u] = tot++;
    11     edge[tot] = (Edge) {u, head[v]}; head[v] = tot++;
    12 }
    13 
    14 bool DFS(int u, int c, int kind) {
    15     if(kind) {
    16         if(col[u] == 1) b++; else a++;
    17     } else {
    18         if(col[u] == 1) ans++;
    19     }
    20     for(int i = head[u]; ~i; i = edge[i].nxt) {
    21         int v = edge[i].v;
    22         if(col[v] == c) return false;
    23         if(!vis[v]) { vis[v] = 1; if(col[v] == 0) col[v] = -c; if(!DFS(v, col[v], kind)) return false; }
    24     }
    25     return true;
    26 }
    27 
    28 int main() {
    29     int n, m;
    30     scanf("%d%d", &n, &m);
    31     memset(head, -1, sizeof(head));
    32     bool flag = 1;
    33     for(int i = 0; i < m; i++) {
    34         int u, v, k;
    35         scanf("%d%d%d", &u, &v, &k);
    36         if(k == 2) {
    37             if(col[u] == -1 || col[v] == -1) flag = 0;
    38             col[u] = col[v] = 1;
    39         } else if(k == 0) {
    40             if(col[u] == 1 || col[v] == 1) flag = 0;
    41             col[u] = col[v] = -1;
    42         } else Add(u, v);
    43     }
    44     for(int i = 1; i <= n; i++)
    45         if(!vis[i] && col[i]) { vis[i] = 1;  if(!DFS(i, col[i], 0)) flag = 0; }
    46     for(int i = 1; i <= n; i++) {
    47         if(vis[i]) continue;
    48         a = 0; b = 0; vis[i] = 1; col[i] = 1;
    49         if(!DFS(i, 1, 1)) flag = 0;
    50         ans += a > b ? b : a;
    51     }
    52     if(!flag) puts("impossible");
    53     else printf("%d
    ", ans);
    54     return 0;
    55 }
  • 相关阅读:
    openfire 介绍安装使用
    android rabbitMQ
    转:socket编程在windows和linux下的区别
    socklen_t在windows和linux平台下的头文件定义
    libevent入门教程
    libevent安装
    《RabbitMQ in action》
    RabbitMQ安装和配置
    node.js模块之http模块
    node.js模块之Buffer模块
  • 原文地址:https://www.cnblogs.com/fightfordream/p/6519248.html
Copyright © 2011-2022 走看看