题目地址:cf#237_div2_C
题目大意:
输入 n,k
告诉你某一个结点到各个结点的最短路(边权值都是1)
问你是否存在一个图,使得每个结点的度数都不超过k;
思路:
直接构造一棵树 ,一层一层的构造
看代码:
#include<iostream>
#include<vector>
#include<cstdio>
using namespace std;
const int maxn=100050;
int n,k;
vector<int> G[maxn];
vector<int> map[maxn];
int d[maxn];
int main()
{
cin>>n>>k;
int max=-1;
for(int i=0;i<n;i++)
{
scanf("%d",&d[i]);
G[d[i]].push_back(i);
if(d[i]>max) max=d[i];
}
bool ok=1;
if(G[0].size()!=1) ok=0;
if(n>1&&G[1].size()>k) ok=0;
long long sa,sb;
for(int i=1;i<max;i++)
{
sa=G[i+1].size();
sb=G[i].size();
sb*=k-1;
if(sa>sb)
{
ok=0;
break;
}
}
if(ok==0) cout<<-1<<endl;
else
{
int ans=0;
for(int i=0;i<max;i++)
{
int index=0;
int size=G[i+1].size();
int kk=(i==0?k:k-1);
for(int j=0;j<G[i].size();j++)
{
int x=G[i][j];
if(map[x].size()<kk)
{
map[x].push_back(G[i+1][index++]);
j--;
ans++;
if(index==size) goto there;
}
}
there:
continue;
}
cout<<ans<<endl;
for(int i=0;i<n;i++)
if(map[i].size())
{
for(int j=0;j<map[i].size();j++)
//if(map[i][j]>i)
cout<<i+1<<' '<<map[i][j]+1<<endl;
}
}
}
1 下一层的结点数不能超过上一层的k-1倍 除了第一层和第0层之间的比较
2 G[i].size()*(k-1) 会暴int
3
第j个结点还没铺满 所以插入一个后,要停在原地,j--
还要监视 这一层是否已经插满了,这样就进入下一层
使用到了goto
for(int j=0;j<G[i].size();j++)
{
int x=G[i][j];
if(map[x].size()<kk)
{
map[x].push_back(G[i+1][index++]);
j--;
ans++;
if(index==size) goto there;
}
}