1. 程式人生 > >Maximum Diameter Graph 【CodeForces - 1082D】【搜尋+構造】

Maximum Diameter Graph 【CodeForces - 1082D】【搜尋+構造】

題目連結


  一開始忘記輸出有多少條邊,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在這,後來發現是因為當時既然已經把最後一個節點處理掉了,就得把它丟掉了。