题目大意:构造一个点数为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 ",edge.size()); 41 for(int i=0;i<edge.size();i++) 42 printf("%d %d ",edge[i].first,edge[i].second); 43 } 44 45 int main(){ 46 read(); 47 work(); 48 return 0; 49 }