Codeforces976D Degree Set 【构造】

题目大意:构造一个点数为dn+1的无向图,无向图中点的度数的集合等于给出的集合d。

题目分析:

  当n=0的时候,一个点即可。

  当n=1的时候,答案是一个包含d1+1个点的完全图。

  否则将d2~dn-1的度数减去d1,然后构造d1个点和dn-dn-1个点,将前d1个点与任何一个点都连上边,这样就有了d1和dn。

 

代码:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 
 4 int n;
 5 int d[520];
 6 
 7 void read(){
 8     scanf("%d",&n);
 9     for(int i=1;i<=n;i++) scanf("%d",&d[i]);
10 }
11 
12 int last = 0;
13 
14 vector<pair<int,int> > edge;
15 
16 void dfs(int l,int r){
17     if(l > r){last = 1;return;}
18     if(l == r){
19     last = d[l]+1;
20     for(int i=1;i<=last;i++)
21         for(int j=i+1;j<=last;j++) edge.push_back(make_pair(i,j));
22     return;
23     }
24     for(int i=l+1;i<r;i++) d[i] -= d[l];
25     dfs(l+1,r-1);
26     for(int i=l+1;i<r;i++) d[i] += d[l];
27     int p1 = d[r]-d[r-1],p2 = d[l];
28     last += p1;
29     for(int i=1;i<=last;i++){
30     for(int j=last+1;j<=last+p2;j++) edge.push_back(make_pair(i,j));
31     }
32     for(int i=last+1;i<=last+p2;i++){
33     for(int j=i+1;j<=last+p2;j++) edge.push_back(make_pair(i,j));
34     }
35     last += p2;
36 }
37 
38 void work(){
39     dfs(1,n);
40     printf("%d\n",edge.size());
41     for(int i=0;i<edge.size();i++)
42     printf("%d %d\n",edge[i].first,edge[i].second);
43 }
44 
45 int main(){
46     read();
47     work();
48     return 0;
49 }

 

posted @ 2018-05-02 14:02  menhera  阅读(439)  评论(0编辑  收藏  举报