K-Subdivision_“范式杯”2023牛客暑期多校训练营1 (nowcoder.com)s
思路挺简单的,当时为什么卡呢……不知道
BFS记录每个点最短路的上一个节点,即可;
判断的时候,如果每个点度只有1,可直接在这条路上加点;
如果度大于1,则统计有无形成其他点最短路中没有用到的边的个数,个数乘能加的点数即可。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n,m,k;
const int maxn=1e5+5;
int dis[maxn];
vector<int> way[maxn];
ll la[maxn];
int main()
{
cin>>n>>m>>k;
memset(dis,127,sizeof(dis));
for(int i=1;i<=m;i++)
{
int x,y;
cin>>x>>y;
way[x].push_back(y);
way[y].push_back(x);
}
queue<int> q;
q.push(1);
dis[1]=0;
ll ans=1;
while(!q.empty())
{
int fr=q.front();
q.pop();
for(auto to:way[fr])
{
if(dis[fr]+1<dis[to])
{
dis[to]=dis[fr]+1;
//cout<<"to"<<to<<" "<<dis[to]<<endl;
la[to]=fr;
q.push(to);
}
}
}
for(int i=2;i<=n;i++)
{
// cout<<dis[i]<<endl;
if(dis[i]>k)
{
continue;
}
//cout<<"i="<<i<<" "<<dis[i]<<"la"<<la[i]<<endl;
ans++;
ll alnum=way[i].size();
// cout<<" "<<alnum<<" "<<nenum<<endl;
if(alnum==1)
{
ans+=(k-dis[i]);
// cout<<"ans"<<ans<<endl;
continue;
}
int tot=0;
for(auto to:way[i])
{
if(to==la[i]||i==la[to])
{
}
else
{
tot++;
}
}
ans+=(k-dis[i])*tot;
// cout<<"ans"<<ans<<endl;
}
cout<<ans<<endl;
return 0;
}