當時因爲__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;
}