1. 程式人生 > >Codeforces 1082D Maximum Diameter Graph (貪心構造)

Codeforces 1082D Maximum Diameter Graph (貪心構造)

scan sca 分析 bits std += 如果 space ont

<題目鏈接>

題目大意:
給你一些點的最大度數,讓你構造一張圖,使得該圖的直徑最長,輸出對應直徑以及所有的邊。

解題分析:
一道比較暴力的構造題,首先,我們貪心的想,要使圖的直徑最長,肯定是盡可能的將所有的頂點連在同一條鏈上,並且,所有度數為1的點都只能作為最外圍的點。所以,基本思想就是先將兩個度為1的頂點放在鏈的兩端(如果有的話),然後所有度>=2的點放在鏈的中間,建好鏈之後,再將多余的度為1的點掛在鏈上最大度數未滿的點上。

#include <bits/stdc++.h>
using namespace std;

const int N = 505;
int n,ind[N]; struct Node{ int ind,loc; bool operator < (const Node &tmp){ return ind>tmp.ind; } }; vector<Node>vec1,vec; int main(){ scanf("%d",&n); for(int i=1;i<=n;i++){ int numd;scanf("%d",&numd); if(numd==1
)vec1.push_back(Node{numd,i}); if(numd>1)vec.push_back(Node{numd,i}); } if(vec1.size()<=2){ if(vec1.size()==0){ printf("YES %d\n",vec.size()-1); printf("%d\n",vec.size()-1); int u=vec[0].loc; for(int i=1;i<vec.size();i++){
int v=vec[i].loc;printf("%d %d\n",u,v); u=v; } }else { if(vec1.size()==1){ printf("YES %d\n",vec.size()); printf("%d\n",vec.size()); int u=vec1[0].loc; for(int i=0;i<vec.size();i++){ int v=vec[i].loc;printf("%d %d\n",u,v); u=v; } }else if(vec1.size()==2){ printf("YES %d\n",vec.size()+1); printf("%d\n",vec.size()+1); int u=vec1[0].loc; for(int i=0;i<vec.size();i++){ int v=vec[i].loc;printf("%d %d\n",u,v); u=v; } printf("%d %d\n",vec[vec.size()-1].loc,vec1[1].loc); } } }else { //如果度為1的點多於2個 int sum=0; for(int i=0;i<vec.size();i++){ vec[i].ind-=2; sum+=vec[i].ind; } if(sum<vec1.size()-2)return puts("NO"),0; printf("YES %d\n",vec.size()+1); printf("%d\n",vec.size()+1+vec1.size()-2); int u=vec1[0].loc; for(int i=0;i<vec.size();i++){ int v=vec[i].loc;printf("%d %d\n",u,v); u=v; } printf("%d %d\n",vec[vec.size()-1].loc,vec1[1].loc); sort(vec.begin(),vec.end()); int pos=0; for(int i=2;i<vec1.size();i++){ vec[pos].ind--; printf("%d %d\n",vec1[i].loc,vec[pos].loc); if(vec[pos].ind==0)pos++; } } }

Codeforces 1082D Maximum Diameter Graph (貪心構造)