CF638C Road Improvement 题解
大致思路:
首先第一个问,我们可以通过贪心策略解决,显然 kkk 是所有点中度数最大的点,因为对于每个点,每天最多修一条边,所以答案必然大于等于最大度数。
后面的问,我们可以定一个节点为根,从根开始遍历,用 vector 存每天建的边,还要记录任意一个节点 uuu 与它父亲节点建边的天数,遇到时需要跳过,随后输出即可。
代码实现:
#include<bits/stdc++.h>
const int N = 3e5 + 10;
const int MOD = 1e9 + 7;
using namespace std;
struct Stream {
enum {
SIZE = 1000001
};
char ibuf[SIZE], *s, *t, obuf[SIZE], *oh;
bool eof;
Stream() : s(), t(), oh(obuf), eof(false) {}
~Stream() { fwrite(obuf, 1, oh - obuf, stdout); }
explicit operator bool() const {
return static_cast<bool>(eof == false);
}
inline char read() {
if (s == t) t = (s = ibuf) + fread(ibuf, 1, SIZE, stdin);
return s == t ? -1 : *s++;
}
inline Stream &operator>>(char *x) {
static char c;
for (c = read(); isspace(c); c = read())
if (c == -1) {
eof = true;
return *this;
}
for (; !isspace(c); c = read()) *x = c, ++x;
*x = 0;
return *this;
}
template<typename T>
inline Stream &operator>>(T &x) {
static char c;
static bool iosig;
for (c = read(), iosig = false; !isdigit(c); c = read()) {
if (c == -1) {
eof = true;
return *this;
}
iosig |= c == '-';
}
for (x = 0; isdigit(c); c = read()) x = x * 10 + (c ^ '0');
if (iosig) x = -x;
return *this;
}
inline void print(char c) {
if (oh == obuf + SIZE) {
fwrite(obuf, 1, SIZE, stdout);
oh = obuf;
}
*oh++ = c;
}
template<typename T>
inline void print(T x) {
static int buf[40], cnt;
if (x != 0) {
if (x < 0) print('-'), x = -x;
for (cnt = 0; x; x /= 10) buf[++cnt] = x % 10 | 48;
while (cnt) print((char) buf[cnt--]);
} else print('0');
}
template<typename T>
inline Stream &operator<<(const T &x) {
print(x);
return *this;
}
inline void print(const char *x) {
for (; *x; x++)
print(*x);
}
} io;
#ifndef DEBUG
#define cin io
#define cout io
#define endl '\n'
#endif
vector < pair < int, int > > f[N];
vector < int > g[N];
int n, dep[N], mx;//dep存度数,通过贪心思想发现k其实就是最大度数,用mx存
void dfs(int d, int x, int fa)
{
int tmp = 1;
for(int i = 0;i < f[x].size(); ++ i)
{
int xx = f[x][i].first;
int yy = f[x][i].second;
if(xx == fa) continue;
if(tmp == d) ++ tmp;//若现在天数到了 u 与父亲相连的天数,则没法再与儿子连
g[tmp].push_back(yy);
dfs(tmp ++, xx, x);
}
}
int main()
{
cin >> n;
for(int i = 1;i < n; ++ i)
{
int x, y;
cin >> x >> y;
f[x].push_back(make_pair(y, i));
f[y].push_back(make_pair(x, i));
++ dep[x]; ++ dep[y];
}
for(int i = 1;i <= n; ++ i) mx = max(mx, dep[i]);cout << mx << "\n";
dfs(0, 1, 0);
for(int i = 1;i <= mx; ++ i)
{
cout << g[i].size() << " ";
for(int j = 0;j < g[i].size(); ++ j)
{
cout << g[i][j] << " ";
}
cout << "\n";
}
return 0;
}
这样这道题就完成啦!!!