Graph constructive problems are back! This time the graph you are asked to build should match the following properties.
The graph is connected if and only if there exists a path between every pair of vertices.
The diameter (aka "longest shortest path") of a connected undirected graph is the maximum number of edges in the shortest path between any pair of its vertices.
The degree of a vertex is the number of edges incident to it.
Given a sequence of nn integers a1,a2,…,ana1,a2,…,an construct a connected undirected graph of nn vertices such that:
- the graph contains no self-loops and no multiple edges;
- the degree didi of the ii-th vertex doesn't exceed aiai (i.e. di≤aidi≤ai);
- the diameter of the graph is maximum possible.
Output the resulting graph or report that no solution exists.
The first line contains a single integer nn (3≤n≤5003≤n≤500) — the number of vertices in the graph.
The second line contains nn integers a1,a2,…,ana1,a2,…,an (1≤ai≤n−11≤ai≤n−1) — the upper limits to vertex degrees.
Print "NO" if no graph can be constructed under the given conditions.
Otherwise print "YES" and the diameter of the resulting graph in the first line.
The second line should contain a single integer mm — the number of edges in the resulting graph.
The ii-th of the next mm lines should contain two integers vi,uivi,ui (1≤vi,ui≤n1≤vi,ui≤n, vi≠uivi≠ui) — the description of the ii-th edge. The graph should contain no multiple edges — for each pair (x,y)(x,y) you output, you should output no more pairs (x,y)(x,y) or (y,x)(y,x).
题意:输入n个点的度,输出能否成为连通图和图的最大直径,和构成连通图的连接边。
思路:首先我们先看这个能不能连成图,每个点之间相连的话,度数和要大于等于2*n-2。图连接的方法现将度数大于1的连成一条链,再将剩下的连在图的两边,就可以想得到最优解。
1 #include <vector> 2 #include <string> 3 #include <iostream> 4 #include <string.h> 5 #include <sstream> 6 #include <cstdio> 7 #include <map> 8 using namespace std; 9 const int inf = 0x3f3f3f3f; 10 const int Maxn = 10010; 11 int a[Maxn]; 12 typedef long long ll; 13 int tot=0; 14 15 int main() 16 { 17 int n; 18 scanf("%d",&n); 19 int sum = 0; 20 for(int i=0;i<n;i++) 21 scanf("%d",&a[i]),sum+=a[i]; 22 if(sum<2*n-2) {cout<<"NO\n"<<endl; return 0;}//判断能否形成连通图 23 vector<int> one; 24 for(int i=0;i<n;i++)//将度为1的挑选出来 25 { 26 if(a[i]==1) 27 a[i]=0,one.push_back(i); 28 } 29 int t=one.size(); 30 cout<<"YES "<<n-t-1+min(2,t)<<endl<<n-1<<endl;//连通图的边数等于点减一 31 int lst=-1; 32 if(!one.empty()) 33 { 34 lst = one.back(); 35 one.pop_back(); 36 } 37 for(int i=0;i<n;i++)//将度数大于1的连成链 38 { 39 if(a[i]>1) 40 { 41 if(lst != -1) 42 { 43 --a[lst]; 44 --a[i]; 45 printf("%d %d\n",lst+1,i+1); 46 } 47 lst = i; 48 } 49 } 50 for(int i=n-1;i>=0;i--)//将度数等于1的尽量连在右侧 51 { 52 while(a[i]>0&&!one.empty()) 53 { 54 --a[i]; 55 printf("%d %d\n",i+1,one.back()+1); 56 one.pop_back(); 57 } 58 } 59 return 0; 60 }