uva 10720 - Graph Construction

Problem C

Graph Construction

Time Limit

2 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.

Input
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.

Output
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.

Sample Input

Output for Sample Input

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

Possible
Not possible
Not possible


Problemsetter: Md. Bahlul Haider
Judge Solution: Mohammed Shamsul Alam
Special thanks to Tanveer Ahsan
補充了個知識點,自己只能想到n個節點圖的度數和小於等於n*(n-1),每個節點度數小於n,度數和爲偶數;
學習了個定理:
Havel定理:
   描述: 我們把序列排成不增序,即d1>=d2>=...>=dn,則d可簡單圖化當且僅當d'=(d2-1, d3-1, ... d(d1+1)-1, d(d1+2), d(d1+3), ... dn)可簡單圖化。這個定理寫起來麻煩,實際上就是說,我們把d排序以後,找出度最大的點(設度爲d1),把它和度次大的d1個點之間連邊,然後這個點就可以不管了,一直繼續這個過程,直到建出完整的圖,或出現負度等明顯不合理的情況。

舉例:序列S7,7,4,3,3,3,2,1  刪除序列S的首項 ,對其後的7項每項減1,得到:6,3,2,2,2,1,0,繼續刪除序列的首項6,對其後的6項每項減1,得到:2,1,1,1,0-1,到這一步出現了負數,因此該序列是不可圖的。

  其實仔細想想,就是貪心的構建一個圖,一條邊對應2個點產生兩個度數,每次拿掉一個度數最大的點刪掉與之相連的邊(有點拓撲排序的意思),與之相連的點度數自然-1;因爲要儘可能連成圖,當然是讓度數大的點度數減少1,否則度數小的點減沒了,就不能構成圖了;
#include<stdio.h>
#include<algorithm>
using namespace std;
int main()
{
 int n,s,a[10000],f,i;
 while (scanf("%d",&n),n)
 {
  s=0; f=0;
  for (i=1;i<=n;i++)
  {
   scanf("%d",&a[i-1]);
   s+=a[i-1];
   if (a[i-1]>n) f=1;
  }
  if (s>n*(n-1) || s%2 || f) printf("Not possible\n");
  else
  {n--;
   while (n)
   {
    sort(a,a+n);
    if (a[n]) {
               for (i=n-1;i>=n-a[n]&&i>=0;i--)
               {--a[i]; if (a[i]<0) f=1;}
              }
     --n;
    if (f) break;
    }
       if (f) printf("Not possible\n");
         else printf("Possible\n");
  }
 }
 return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章