Maximum Diameter Graph 【CodeForces - 1082D】【搜索+构造】

版权声明:https://blog.csdn.net/qq_41730082 https://blog.csdn.net/qq_41730082/article/details/84972478

题目链接


  一开始忘记输出有多少条边,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在这,后来发现是因为当时既然已经把最后一个节点处理掉了,就得把它丢掉了。

猜你喜欢

转载自blog.csdn.net/qq_41730082/article/details/84972478