题意:
有n个城市,给出n-1条双向道路使它们都相互连通,每天可选择任意多不相邻的路维修,每条路一天就可以修完,求出最少多少天可以把所有的路都修完。
思路:
因为有n个点,n-1条边,所以是一棵树,用DFS对其遍历,只要相邻的两条路维修的那一天不一样即可,例如如果有一条边第2天维修,它有三条相邻的边,则可依次在第1、3、4天维修,对每条边以此类推,类似于图染色问题。
#include <iostream>
#include <vector>
#include <utility>
#include <cstdio>
using namespace std;
#define FIO ios_base::sync_with_stdio(false); cin.tie(nullptr);
#define FILEREAD freopen("input.txt", "r", stdin);
const int INF = 0x3f3f3f3f;
const int N = 200001;
vector<pair<int, int>> v[N];
vector<int> ans[N];
int k = 0;
void dfs(int curv, int prev, int curtime)
{
int fixtime = 0;
for (auto i : v[curv])
{
int nextv = i.first;
if (nextv != prev)
{
++fixtime;
if (fixtime == curtime)
++fixtime;
if (fixtime > k)
k = fixtime;
ans[fixtime].push_back(i.second);
dfs(nextv, curv, fixtime);
}
}
}
int main()
{
#ifndef ONLINE_JUDGE
FILEREAD
#endif
FIO
int n;
cin >> n;
for (int i = 1; i < n; ++i)
{
int u, w;
cin >> u >> w;
v[u].push_back({w, i});
v[w].push_back({u, i});
}
dfs(1, 0, 0);
cout << k << endl;
for (int i = 1; i <= k; ++i)
{
cout << ans[i].size() << " ";
for(int d : ans[i])
cout << d << " ";
cout << endl;
}
return 0;
}