UVA 10720 Graph Construction 贪心+优先队列

本文针对一个特定的图构造问题进行了解析,通过给定每个顶点的度数判断是否能够组成无环无平行边的无向图。采用贪心算法解决此问题,详细介绍了算法的实现过程,并给出了完整的代码示例。

题目链接:

题目

Graph Construction
Time limit: 3.000 seconds

问题描述

Graph is a collection of edges E and vertices V. Graph has a wide variety of applications in computer.
There are different ways to represent graph in computer. It can be represented by adjacency matrix or
by adjacency list. There are some other ways to represent graph. One of them is to write the degrees
(the numbers of edges that a vertex has) of each vertex. If there are n vertices then n integers can
represent that graph. In this problem we are talking about simple graph which does not have same
endpoints for more than one edge, and also does not have edges with the same endpoint.
Any graph can be represented by n number of integers. But the reverse is not always true. If you
are given n integers, you have to find out whether this n numbers can represent the degrees of n vertices
of a graph.

输入

Each line will start with the number n (≤ 10000). The next n integers will represent the degrees of n
vertices of the graph. A ‘0’ input for n will indicate end of input which should not be processed.

输出

If the n integers can represent a graph then print ‘Possible’. Otherwise print ‘Not possible’. Output
for each test case should be on separate line.

样例

input
4 3 3 3 3
6 2 4 5 5 2 1
5 3 2 3 2 1
0

output
Possible
Not possible
Not possible

题意

给你每个顶点的度数,问能不能组成无环无平行边的无向图。

题解

贪心做:
从最大度数的那个点(假设度数是x)做开始,在剩下的数中选出度最大的前x个数,如果有哪个节点的度数为0则不可能构成图,否则把这些节点度数减1继续做。 直到所有的点的度数都为0。

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;

int main(){ 
    int n;
    while(scanf("%d",&n)==1&&n){
        priority_queue<int> pq;
        int x;
        for(int i=0;i<n;i++){
            scanf("%d",&x);
            pq.push(x); 
        }
        bool su=1;
        while(!pq.empty()){
            int u=pq.top(); pq.pop();
            if(u==0) break;
            vector<int> pool;
            for(int i=0;i<u;i++){
                if(pq.empty()){
                    su=0; break;
                }
                int v=pq.top(); pq.pop();
                if(v==0){
                    su=0; break;
                }
                v--;
                pool.push_back(v);
            }
            if(!su) break;
            for(int i=0;i<pool.size();i++){
                pq.push(pool[i]);
            }
        }
        if(su) puts("Possible");
        else puts("Not possible"); 
    } 
    return 0;
}

转载于:https://www.cnblogs.com/fenice/p/5671564.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值