CF1141G
解析
我们贪心地想,要使公司最少,那肯定要把
那现在需要解决:要怎么分配?可以遍历树,每到一个点时保证它的父边已经完成分配。那么被我们钦定为不好城市的显然可以把全部子边赋成
于是就做完了,时间复杂度
AC 记录
:::success[参考代码]
#include<iostream>
#include<algorithm>
#include<vector>
#define int long long
using namespace std;
const int N=2e5+5;
int n,k;
struct node
{
int z,id;
}d[N];
vector<pair<int,int>> v[N];
int ys[N];
bool flag[N];
inline bool cmp(node x,node y)
{
return x.z>y.z;
}
inline int read(){int out=0,fh=1;char cc=getchar();while((cc>'9' || cc<'0') && cc!='-'){cc=getchar();}if(cc=='-'){fh=-1;}while(cc>'9' || cc<'0'){cc=getchar();}while(cc>='0' && cc<='9'){out=out*10+cc-'0';cc=getchar();}return out*fh;}
inline void write(int x){if(x<0){x=-x;putchar('-');}if(x==0){putchar('0');return ;}int num=0;char c[60];while(x){c[++num]=(x%10)+48;x/=10;}while(num){putchar(c[num--]);}}
inline string readstr(){string ans="";char cc=getchar();while(cc==' ' || cc=='\r' || cc=='\n'){cc=getchar();}while(cc!=' ' && cc!='\r' && cc!='\n' && cc!=EOF){ans+=cc;cc=getchar();}return ans;}
inline void writestr(string s){int sz=s.size();for(int i=0;i<sz;i++){putchar(s[i]);}}
inline char readchar(){char cc=getchar();while(cc==' ' || cc=='\r' || cc=='\n'){cc=getchar();}return cc;}
inline void dfs(int d,int fa,int fbs)
{
if(flag[d])
{
for(auto t:v[d])
{
int v=t.first,h=t.second;
if(v==fa) continue;
ys[h]=1;
dfs(v,d,1);
}
return ;
}
int tot=0;
for(auto t:v[d])
{
int v=t.first,h=t.second;
if(v==fa) continue;
++tot;
if(tot==fbs) ++tot;
ys[h]=tot;
dfs(v,d,tot);
}
}
signed main()
{
n=read(),k=read();
for(int i=1;i<n;i++)
{
d[i].id=i;
int x=read(),y=read();
++d[x].z;
++d[y].z;
v[x].push_back(make_pair(y,i));
v[y].push_back(make_pair(x,i));
}
d[n].id=n;
sort(d+1,d+1+n,cmp);
for(int i=1;i<=k;i++)
{
flag[d[i].id]=true;
}
write(max(1LL,d[k+1].z));
putchar('\n');
dfs(1,0,0);
for(int i=1;i<n;i++)
{
write(ys[i]);
putchar(' ');
}
return 0;
}
/*
我是cjn,补肘啦,快速补充愤怒值
*/
:::