码迷,mamicode.com
首页 > 其他好文 > 详细

【HDU】HDU5285 贪心+二分染色

时间:2015-07-21 01:05:30      阅读:139      评论:0      收藏:0      [点我收藏+]

标签:

基础稍微可以了,来练练手= =

题目意思:

给你N个小朋友,他们之间有M个关系,表示Ai小朋友不认识Aj小朋友

现在需要把他们划为两个集合,要求集合中小朋友不能互不认识

若不能则输出“Poor wyh”

若能,则需要第一个集合尽可能的多,并输出两个集合小朋友数量

 

思路:

首先是染色判定,这是必要的

然后贪心,当时这一步想了比较长时间

对于一个每一个新加入的节点,总会带来两个颜色集合点数量的增长

我们只需要每次把增长多的那个放进第一个集合就可以了

注意有个坑!当所有小朋友都认识的时候(即M为0)

不能将他们全都放在一个集合里得分出一个到集合2!

 

附上代码:

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <string>
#include <math.h>
#include <stack>
#include <queue>
#include <vector>
#include <map>
#include <set>
#pragma warning(disable:4996)

#define Zero(a) memset(a, 0, sizeof(a))
#define Neg(a)  memset(a, -1, sizeof(a))
#define All(a) a.begin(), a.end()
#define PB push_back
#define repf(i,a,b) for(i = a;i <= b; i++)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define root 1,n,1
#define ll long long
#define MAXN 100005
#define mod 1000000007
using namespace std;

vector <int> mp[MAXN];
int col[MAXN];
int n, m, num[3];

bool dfs(int u, int color){
    col[u] = color;
    num[col[u]]++;
    for (int i = 0; i < mp[u].size(); ++i){
        int v = mp[u][i];
        if (col[v]){
            if (col[v] != 3 - col[u]) return false;
        }
        else{
            if (!dfs(v, 3 - color))return false;
        }
    }
    return true;
}

int main(){
    int T;
    int u, v;
    while (~scanf("%d", &T)){
        while (T--){
            scanf("%d%d", &n, &m);
            for (int i = 0; i <= n; ++i){
                mp[i].clear();
                col[i] = 0;
            }
            for (int i = 0; i < m; ++i){
                scanf("%d%d", &u, &v);
                mp[u].push_back(v);
                mp[v].push_back(u);
            }
            num[1] = num[2] = 0;
            int ans1 = 0, ans2 = 0;
            bool flag = true;
            for (int i = 1; i <= n; ++i){
                if (!col[i]){
                    int pt1 = num[1], pt2 = num[2];
                    if (!dfs(i, 1)){
                        flag = false;
                        break;
                    }
                    ans1 += max(num[1] - pt1, num[2] - pt2);
                    ans2 += min(num[1] - pt1, num[2] - pt2);
                    num[1] += pt1, num[2] += pt2;
                }
            }
            if (ans2 == 0) ans1--, ans2++;
            if (!flag || n <= 1)
                printf("Poor wyh\n");
            else
                printf("%d %d\n", ans1, ans2);
        }
    }
    return 0;
}

 

【HDU】HDU5285 贪心+二分染色

标签:

原文地址:http://www.cnblogs.com/mashiroG/p/4662954.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!