pku1659

/*
 * File:   pku1659.cpp
 * 题意:给定一些点的度数,问根据这些度数能否构成一个图。
 * 根据大牛说的Havel定理进行贪心。
 * Author: chenjiang
 *
 * Created on 2010年5月13日, 下午9:24
 */

#include <stdlib.h>
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
int mapmap[11][11];

struct node {
    int id;
    int degree;
} v[11];

int cmp(const node&a, const node&b) {
    return a.degree > b.degree;
}

/*
 *
 */
int main(int argc, char** argv) {

    int i, j, T, n;
    int s;
    //freopen("a.a", "r", stdin);
    cin >> T;
    for (s = 1; s <= T; s++) {
        cin >> n;
        for (i = 1; i <= n; i++) {
            cin >> v[i].degree;
            v[i].id = i;
        }
        memset(mapmap, 0, sizeof (mapmap));
        bool flag = 1;
        for (i = 1; i <= n; i++) {
            sort(v + 1, v + n + 1, cmp);//根据度从大到小排序
            int next = v[1].degree;//next保存最大的度
            if (next <= 0)break;
            v[1].degree = 0;//最大的度置0
            for (j = 2; j <= next + 1; j++) {//这个地方wa了我很久,没注意要+1,囧
                v[j].degree--;//以后每个点的度减1
                if (v[j].degree < 0) {//如果某个点的度出现了负数,则不能构成一个图
                    flag = 0;
                    break;
                }
                mapmap[v[1].id][v[j].id] = 1;//连边
                mapmap[v[j].id][v[1].id] = 1;
            }
            if (flag == 0)break;
        }
        for (i = 1; i <= n; i++) {
            if (v[i].degree != 0) {//如果还存在非零的度,则不能构成一个图
                flag = 0;
                break;
            }
        }
        if (flag) {
            cout << "YES" << endl;
            for (i = 1; i <= n; i++) {
                for (j = 1; j <= n; j++) {
                    if (j != n) {
                        cout << mapmap[i][j] << " ";
                    } else {
                        cout << mapmap[i][j] << endl;
                    }
                }
            }
            if (s != T)cout << endl;
        } else {
            cout << "NO" << endl;
            if (s != T)cout << endl;
        }
    }
    return (EXIT_SUCCESS);
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值