zoukankan      html  css  js  c++  java
  • POJ1112 Team Them UP!

    题面

    你的任务是以下列方式将一些人分成两个小队:

    1、每个人都属于其中一个团队;
    2、每个团队至少有一名成员;
    3、团队中的每个人都认识团队中的每个人;
    4、团队的规模尽可能接近。

    此任务可能有许多解决方案,你可以输出任何一种解决方案,或声明解决方案不存在。

    输入格式

    第一行包含整数N,表示共有N个人,他们被编号为1,2,…,N。

    接下来N行,第 i 行包含多个用空格分隔开的整数,表示编号为i的人认识的人的编号列表,最后以0结尾。

    注意A认识B不代表B一定认识A。

    输出格式

    如果不存在解决方案,则输出”No solution”。

    如果存在,则输出两个队伍的成员信息,每个队伍占一行,首先输出队伍的人数,然后依次输出队伍成员的编号。

    数据范围

    2≤N≤100
    

    输入样例:

    5
    2 3 5 0
    1 4 5 3 0
    1 2 5 0
    1 2 3 0
    4 3 2 1 0
    

    输出样例:

    3 1 3 5
    2 2 4
    

    题解

    明显的建反边, 染色分组, 然后为了使得两队人数差最小, 用背包

    但是! 我们可以贪心!

    我们按照每次染色后的两组的差值排序, 从大到小, 贪心选就好了

    小生bb, 都0202年了, poj还不支持c++11吗?

    代码

    int h[N][N], v[N];
    vector<pair<VI, VI > > ans;
    
    bool dfs(int x, int c) {
        if (c == 1) v[x] = 1, ans.back().fi.pb(x);
        else v[x] = 2, ans.back().se.pb(x);
        rep (y, 1, n) {
            if (!h[x][y] || v[y] == 3 - c) continue;
            if (v[y] && v[y] == c) return 1;
            if (dfs(y, 3 - c)) return 1;
        }
        return 0;
    }
    
    bool cmp(const pair<VI, VI> &a, const pair<VI, VI> &b) {
        return abs((int)a.fi.size() - (int)a.se.size()) > abs((int)b.fi.size() - (int)b.se.size());
    }
    
    int main() {
        IOS; cin >> n;
        rep (i, 1, n) rep (j, i + 1, n) h[i][j] = h[j][i] = 1;
        rep (i, 1, n) while (cin >> m, m) h[i][m] = 0;
        rep (i, 1, n) rep (j, 1, n) if (h[i][j]) h[j][i] = 1;
        rep (i, 1, n) 
            if (!v[i]) {
                ans.pb({ VI(), VI() });
                if (dfs(i, 1)) { cout << "No solution"; return 0;}
            }
        sort(all(ans), cmp);
        VI &a = ans[0].fi, &b = ans[0].se;
        for (int i = 1; i < ans.size(); ++i)
            if (ans[i].fi.size() >= ans[i].se.size())
                if (a.size() >= b.size()) a.insert(a.end(), all(ans[i].se)), b.insert(b.end(), all(ans[i].fi));
                else b.insert(b.end(), all(ans[i].se)), a.insert(a.end(), all(ans[i].fi));
            else
                if (a.size() >= b.size()) b.insert(b.end(), all(ans[i].se)), a.insert(a.end(), all(ans[i].fi));
                else a.insert(a.end(), all(ans[i].se)), b.insert(b.end(), all(ans[i].fi));
        sort(all(a)); sort(all(b));
        cout << a.size(); rep (i, 0, a.size() - 1) cout << ' ' << a[i];
        cout << '
    ' << b.size(); rep (i, 0, b.size() - 1) cout << ' ' << b[i];
        return 0;
    }
    
  • 相关阅读:
    redis conf 中文详解
    sed 用法记录
    MySQL数据库的各种存储引擎详解
    MySQL数据库char与varchar的区别分析及使用建议
    从一个乘法来分析C语言
    排它平方数
    高斯日记
    SUID或SGID程序中能不能用system函数
    【转载】GDB反向调试(Reverse Debugging)
    setuid函数解析
  • 原文地址:https://www.cnblogs.com/2aptx4869/p/13752063.html
Copyright © 2011-2022 走看看