题目大意:
给出N个点的一棵树,每个点现在都有一个施工队,如果重新修建一条边需要一条边两侧的施工队同时工作才行。
现在问最少多少天,能够使得所有边都重建完成;
思路:
Dfs一遍即可,对于一个点来讲,其往下走的时候,每条边的工作天数都肯定不同。
再维护一个天数,即父亲点和当前点修建这条边的天数编号x,对应这个当前点和其儿子节点之间的修建工作,我们再从第一天开始分配工作,如果遇到了和x编号相同的时候,我们天数++即可。
具体参考代码。
Ac代码:
#include<stdio.h>
#include<string.h>
#include<map>
#include<vector>
using namespace std;
vector<int>mp[250000],ans[250000];
int output;
map<pair<int,int>,int>s;
void Dfs(int u,int from,int prenum)
{
int day=0;
for(int i=0;i<mp[u].size();i++)
{
int v=mp[u][i];
if(v==from)continue;
day++;if(prenum==day)day++;
ans[day].push_back(s[make_pair(u,v)]);
Dfs(v,u,day);
}
output=max(output,day);
}
int main()
{
int n;
while(~scanf("%d",&n))
{
s.clear();
output=0;
for(int i=1;i<=n;i++)mp[i].clear(),ans[i].clear();
for(int i=1;i<=n-1;i++)
{
int x,y;scanf("%d%d",&x,&y);
mp[x].push_back(y);
mp[y].push_back(x);
s[make_pair(x,y)]=s[make_pair(y,x)]=i;
}
Dfs(1,-1,0);
printf("%d\n",output);
for(int i=1;i<=output;i++)
{
printf("%d ",ans[i].size());
for(int j=0;j<ans[i].size();j++)
{
int v=ans[i][j];
printf("%d ",v);
}
printf("\n");
}
}
}