Codeforces 638C Road Improvement(DFS)

Posted by Scalpel on April 3, 2016

题目链接

题意:

有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;
}