4768: 【USACO2014OPEN】牧场装饰{bronze题3}

Memory Limit:256 MB Time Limit:15.000 S
Judge Style:Text Compare Creator:
Submit:3 Solved:1

Description

1. 牧场装饰{bronze3}

【问题描述】

农民约翰有N(1<= N<=50,000)牧场,分别编号为1... N。牧场由M(1<= M<=100,000)条双向道路连接。道路i连接两个不同的牧场牧场A_i(1<= A_I<= N)和牧场B_i(1<= B_i<= N)。同一对牧场之间可能有多条道路连接。

现对每个牧场摆放一块标有大写字母”F”或者”J”的广告牌进行装饰。两个有道路相连的牧场,必须摆放不同字母的广告牌。

“F”字母广告牌的价格要高于”J”字母的广告牌,所以约翰想最大化地使用”J”字母广告牌,请输出这个最大的数目,如果没有可行的摆放方案,则输出”-1”。

【文件输入】

第一行为两个整数N和M。

接下来2..M行,每行两个整数,描述M条双向道路。

【文件输出】

   输出共一行,一个整数,表示”J”字母广告牌的最大数目,无解则输出”-1”。

【输入样例1】

4 4

1 2

2 3

3 4

4 1

【输出样例1】

2

【样例1说明】

牧场1和3,或者牧场2和4使用”J”字母广告牌。

Sample Input Copy


Sample Output Copy


HINT

Analysis: Decorating The Pastures by Kalki Seksaria


This is a variant of the problem of determining if a graph is 2-colorable. We can start by considering the case where all the pastures are connected. For now, we can ignore the costs of the signs, and simply determine if we can place the signs such that two pastures are decorated with different letters if they are connected by a path. Without loss of generality, we can start by guessing that the first pasture will have an 'F'. Now, all of our decisions as to whether to place an 'F' or a 'J' at any other vertex are forced. We can DFS, and place an 'F' on every vertex that has a neighboring pasture with a 'J', and vice-versa. If this procedure is successful, we have found a valid assignment of the signs. Now, the only decision we made was to decide whether pasture 1 would have an 'F' or a 'J'. If the number of 'J' signs in this assignment is at least as large as the number of 'F' signs, then we are good. If not, we can simply reverse all of the 'F' and 'J' signs. This gives us the maximum number of 'J' signs. If this assignment procedure is unsuccessful, and results in one pasture needing both an 'F' sign and a 'J' sign, then a valid assignment cannot be found and we should output -1. We can now generalize this to graphs where not all of the pastures are connected by solving each connected component separately. If even one connected component is unsuccessful, then we should output -1. If the assignment for all the connected components is successful, then the maximum number of 'J' signs is just the sum of this quantity for all the connected components.

Here is Mark's code:

#include <iostream>
#include <vector>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cassert>

using namespace std;

#define MAXN 50010

int color[MAXN];
int colorcount[2];
vector<int> E[MAXN];

bool dfs(int u, int c) {
  if(color != -1) return color == c;
  color = c;
  colorcount[c]++;

  for(int i = 0; i < E.size(); i++) {
    if(!dfs(E[i], 1 - c)) {
      return false;
    }
  }
  return true;
}

int main() {
  freopen("decorate.in", "r", stdin);
  freopen("decorate.out", "w", stdout);

  int N, M;
  cin >> N >> M;
  assert(1 <= N && N <= 50000);
  assert(1 <= M && M <= 100000);
  for(int i = 0; i < M; i++) {
    int u, v;
    cin >> u >> v;
    assert(u != v);
    assert(1 <= u && u <= N);
    assert(1 <= v && v <= N);
    u--; v--;

    E.push_back(v);
    E[v].push_back(u);
  }

  int ccnt = 0;
  int result = 0;
  memset(color, -1, sizeof(color));
  for(int i = 0; i < N; i++) {
    if(color[i] != -1) continue;
    ccnt++;
    colorcount[0] = colorcount[1] = 0;
    if (!dfs(i, 0)) {
      result = -1;
      break;
    }
    result += max(colorcount[0], colorcount[1]);
  }
  cout << result << endl;

  return 0;
}