题目链接:CodeForces-1082D Maximum Diameter Graph
题意
有n个点,第i个点最大的度为$a_i$,求令图连通后直径最大的构图方案。
思路
判断是否能构造一个连通图,如果可以的话,将所有度数大于1的点连成一条线,剩下度为一点尽量连一下最左边和最右边的点,然后随便连即可,这样贪心一定是最优的。
实现代码
1 #include <cstdio> 2 const int maxn = 510; 3 struct Node 4 { 5 int deg, idx; 6 } no[maxn]; 7 struct Edge 8 { 9 int u, v; 10 } ed[maxn]; 11 int no1[maxn]; 12 13 int main() { 14 int n; 15 while (~scanf("%d", &n)) { 16 int cnt = 0, cnt1 = 0, tot = 0, sum = 0, ai; 17 for (int i = 1; i <= n; i++) { 18 scanf("%d", &ai); 19 sum += ai; 20 if (ai > 1) no[cnt++] = {ai, i}; 21 else no1[cnt1++] = i; 22 } 23 if (sum < (n - 1) * 2) { 24 puts("NO"); 25 continue; 26 } 27 int ans1 = 0, ans2 = 0; 28 for (int i = 0; i < cnt - 1; i++) { 29 ed[ans2++] = {no[i].idx, no[i+1].idx}; 30 no[i].deg--, no[i+1].deg--; 31 ans1++; 32 } 33 if (cnt1) { 34 ed[ans2++] = {no1[cnt1-1], no[0].idx}; 35 no[0].deg--; 36 ans1++; 37 cnt1--; 38 } 39 if (cnt1) { 40 ed[ans2++] = {no1[cnt1-1], no[cnt-1].idx}; 41 no[cnt-1].deg--; 42 ans1++; 43 cnt1--; 44 } 45 while (cnt1) { 46 for (int i = 0; i < cnt; i++) { 47 if (no[i].deg) { 48 ed[ans2++] = {no[i].idx, no1[cnt1-1]}; 49 no[i].deg--; 50 cnt1--; 51 } 52 if (cnt1 == 0) break; 53 } 54 } 55 printf("YES %d ", ans1); 56 printf("%d ", ans2); 57 for (int i = 0; i < ans2; i++) printf("%d %d ", ed[i].u, ed[i].v); 58 } 59 return 0; 60 }