当时因为__int128不能用,然后E题爆long long 花了好长时间,其实不用二分。。。直接算出来。
其次这场的C题因为无解数据可能导致数组越界,而且爆int,所以被hack了= =
还是得多打div3练习思维严密性,快速想到坑点。
然后这个G题半个小时硬是冇得想法,二分答案以后不知道怎么办,因为想到一个点把他的边全部染色以后,枚举到其他点的时候有一些边已经被染过色了,于是就不知道怎么办了,感觉得每个点开个set,然而又要考虑到这个点要是超出r,要给那些重复颜色的点安排哪些颜色的问题,不知道怎么做了。
看了题解。。。原来直接按照dfs顺序,由于这是一棵树,所以和父节点只有一条边重复,那么这样就直接枚举下去就行了,跳过父边的颜色一次,第二次就算他重复了。
那么这样可以直接算出r了,当du[i]>r的个数恰好小于等于r时就行。
2500分的题还是做不来,菜哭.jpg
#include<bits/stdc++.h>
#define maxl 200010
using namespace std;
int n,k,cnt,r;
int ans[maxl],ehead[maxl],du[maxl],num[maxl];
struct ed
{
int nxt,to,ind;
}e[maxl<<1];
inline void add(int u,int v,int i)
{
e[++cnt].to=v;e[cnt].nxt=ehead[u];ehead[u]=cnt;
e[cnt].ind=i;
}
inline void prework()
{
scanf("%d%d",&n,&k);
int u,v;
for(int i=1;i<=n-1;i++)
{
scanf("%d%d",&u,&v);
add(u,v,i);add(v,u,i);
du[u]++;du[v]++;
}
for(int i=1;i<=n;i++)
num[du[i]]++;
int sum=0;
for(int i=n;i>=1;i--)
{
sum+=num[i];
if(sum>k)
{
r=i;
return;
}
}
}
inline void dfs(int u,int fa,int fcol)
{
int v;int col=1;
for(int i=ehead[u];i;i=e[i].nxt)
{
v=e[i].to;
if(v==fa) continue;
if(col==fcol)
{
col=col+1;
if(col>r) col=1;
fcol=0;
}
ans[e[i].ind]=col;
dfs(v,u,col);
col=col+1;
if(col>r) col=1;
}
}
inline void mainwork()
{
dfs(1,0,0);
}
inline void print()
{
printf("%d\n",r);
for(int i=1;i<=n-1;i++)
printf("%d ",ans[i]);
}
int main()
{
prework();
mainwork();
print();
return 0;
}