UVALive 6957 Hyacinth(DFS)解题报告

2017-02-23 303 次浏览 解题报告

Also available: UVALive 6957, Kattis hyacinth, UESTC 1119

题意

在一个网络中给出 n 个节点,每个节点最多可以有两种频率,又给出 n-1 条边(题目保证形成树),要求每条边上的两个节点必须至少有一种频率相同,如果一种频率两个相连的节点所使用,那么这种频率就算做已使用的频率。要求使已使用频率的种数尽可能多,输出每个节点的频率。

解题思路

DFS 一下,每个节点的第一种频率继承父节点的频率。为了使已用频率种数尽可能多,需要尽量分配新的频率,所以要给当前节点的第二种频率分配一种新的频率,并且优先给孩子节点分配新的频率。所以我们可以给第一个分配第二种频率,其他孩子节点分配第一种频率(也可以第二种/第一种交替分配)。

参考代码

#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;

const int MAXN = 10001;

vector<int> edges[MAXN];
int freq[MAXN][2], idx;

void DFS(int u, int p, int f) {
    freq[u][0] = f;
    freq[u][1] = idx++; // 第二种频率设为新频率
    int cnt = 0;
    for(int i=0; i<edges[u].size(); ++i) {
        int v = edges[u][i];
        if(v != p) {
            if(cnt == 0) DFS(v, u, freq[u][1]); // 优先分配新频率
            else DFS(v, u, freq[u][0]);
            cnt++;
        }
    }
}

int main(int argc, char const *argv[]) {
    int n, u, v;
    while(~ scanf("%d", &n)) {
        for(int i=1; i<=n; ++i) {
            edges[i].clear();
        }
        for(int i=0; i<n-1; ++i) {
            scanf("%d %d", &u, &v);
            edges[u].push_back(v);
            edges[v].push_back(u);
        }
        if(n == 2) printf("0 1\n1 0\n");
        else {
            idx = 1;
            DFS(1, -1, 0);
            for(int i=1; i<=n; ++i) {
                printf("%d %d\n", freq[i][0], freq[i][1]);
            }
        }
    }
    
    return 0;
}

bLue 创作,采用 知识共享署名 3.0,可自由转载、引用,但需署名作者且注明文章出处。
本文地址:https://dreamer.blue/blog/post/2017/02/23/uvalive-6597.dream

还不快抢沙发

添加新评论