1. 程式人生 > >cf1082D Maximum Diameter Graph(構造+模擬+細節)

cf1082D Maximum Diameter Graph(構造+模擬+細節)

題目連結

QWQ不得不說 c f cf e d u   r

o u n d edu\ round 出這種東西 有點太噁心了

題目大意:給你 n n

個點,告訴你每個點的最大度數值(也就是說你的度數要小於等於這個),讓你構造一個無向圖,使其滿足直徑最大且包含所有點

一看就是個構造題
QWQ但是細節非常多。

大致上的思路就是,我們考慮把度數大於1的點拿出來,然後構成一條鏈,剩下的往這條鏈上掛就行,但是掛的時候要注意,優先往最頭上的兩個點掛,因為這樣可以擴大直徑,然後搞一搞就好
QWQ
(其實是強行湊部落格文章數目)

記得特判一下只有一個度數大於1,或者沒有的情況啊!

#include<iostream>
#include<cstdio>
#include<algorithm>
#include
<cstring>
#include<cmath> #include<vector> #define mk make_pair using namespace std; inline int read() { int x=0,f=1;char ch=getchar(); while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();} while (isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();} return x*f; } const int maxn = 2010; vector<pair<int,int> > ans; vector<int> v; int a[maxn]; int n,m; bool flag=1; vector<int> v1; int tmp; int ymh; int main() { n=read(); for (int i=1;i<=n;i++) {// a[i]=read(); if (a[i]>1) v.push_back(i),tmp+=a[i]; } for (int i=1;i<=n;i++) if (a[i]==1) v1.push_back(i); if (v.size()==1) { int pos=0; for (int i=1;i<=n;i++) if (a[i]>1) pos=i; if (tmp>=n-1) { cout<<"YES"<<" "<<min(n-1,2)<<endl; cout<<n-1<<endl; for (int i=1;i<=n;i++) { if (i!=pos) { cout<<i<<" "<<pos<<"\n"; } } } else { cout<<"NO"; } return 0; } if (v.size()==0) { cout<<"NO"; return 0; } for (int i=0;i<v.size()-1;i++) ans.push_back(mk(v[i],v[i+1])),a[v[i]]--,a[v[i+1]]--; ymh = v.size()-1; if (v1.size()==1) { ymh++; ans.push_back(mk(v[0],v1[0])); } int now = 0; if (v1.size()>=2) { ymh+=2; now = 2; ans.push_back(mk(v[0],v1[0])); ans.push_back(mk(v[v.size()-1],v1[1])); a[v[0]]--; a[v[v.size()-1]]--; int i=0; while (i<v.size() && now<v1.size()) { while (i<v.size() && a[v[i]]==0) i++; if (i==v.size()) break; ans.push_back(mk(v[i],v1[now])); now++; a[v[i]]--; } } if (now!=v1.size() && v1.size()>=2) { cout<<"NO"; } else { cout<<"YES"<<" "<<ymh<<endl; cout<<ans.size()<<endl; for (int i=0;i<ans.size();i++) { cout<<ans[i].first<<" "<<ans[i].second<<"\n"; } } return 0; }