Maximum Diameter Graph 【CodeForces - 1082D】【搜尋+構造】
阿新 • • 發佈:2018-12-25
題目連結
一開始忘記輸出有多少條邊,WA了好幾發都跑不過第一組測試樣例,開始懷疑自己是不是讀了道假題,然後在大佬們的幫助下,終於AC,好傷心……讀假樣例(一定是我太弱了)。
我的思想是採用了樹鏈剖分的dfs()構造思想,可能是因為最近少用了樹鏈剖分有些想念吧,我用dfs()去建邊,在此之前先按照節點的度按照降序排列,並且如果最後存在個度為1的節點的話,我們先把它放到第一個上面去就行了。
#include <iostream> #include <cstdio> #include <cmath> #include <string> #include <cstring> #include <algorithm> #include <limits> #include <vector> #include <stack> #include <queue> #include <set> #include <map> #define lowbit(x) ( x&(-x) ) #define pi 3.141592653589793 #define e 2.718281828459045 using namespace std; typedef unsigned long long ull; typedef long long ll; const int maxN = 505; int N, sum_ofdu, num; bool vis[maxN]; struct node { int du, id; node(int a=0, int b=0):du(a), id(b) {} }a[maxN]; bool cmp(node e1, node e2) { return e1.du > e2.du; } struct Eddge { int no, to; Eddge(int a=0, int b=0):no(a), to(b) {} }need[maxN]; int dfs(int u, int fa, int len) { if(fa == N) return len - 1; if(fa != -1) need[++num] = Eddge(a[fa].id, a[u].id); if(a[u].du <= 0 || a[u+1].du <= 0) return len; vis[a[u+1].id] = true; a[u].du--; a[u+1].du--; int ans = dfs(u+1, u, len+1); for(int i=u+1; i<=N && a[u].du; i++) { if(!vis[a[i].id] && a[u].du && a[i].du) { a[u].du--; a[i].du--; vis[a[i].id] = true; dfs(i, u, 0); } } return ans; } int main() { while(scanf("%d", &N)!=EOF) { sum_ofdu = num = 0; memset(vis, false, sizeof(vis)); for(int i=1; i<=N; i++) { scanf("%d", &a[i].du); a[i].id = i; sum_ofdu += a[i].du; } if(sum_ofdu < 2*(N-1)) { printf("NO\n"); continue; } sort(a+1, a+1+N, cmp); int flag = 0; if(a[1].du > 1 && a[N].du == 1) { a[1].du--; a[N].du--; need[++num] = Eddge(a[1].id, a[N].id); vis[a[1].id] = true; vis[a[N].id] = true; flag = 1; } vis[a[1].id] = true; printf("YES %d\n", dfs(1, -1, 0)+flag); printf("%d\n", num); for(int i=1; i<=num; i++) printf("%d %d\n", need[i].no, need[i].to); } return 0; } /* 17 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 2 */
最後放了組測試樣例,答案是16條邊……一開始一直會WA在這,後來發現是因為當時既然已經把最後一個節點處理掉了,就得把它丟掉了。