题意:构造一个有n个顶点,每个点度不超过k,然后给出每一个点到达一个定点的最短距离d数组,然后构造出这样的一个图;
思路:排序之后,有两个距离为0的或者没有直接输出-1,然后用两个游动下表,后面的与前面的度都小于k且它们的距离相差1,就建1条边。然后dfs输出就可以。
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <iostream> 5 #include <cmath> 6 #include <vector> 7 #define maxn 100010 8 using namespace std; 9 10 int n,k; 11 int d[maxn]; 12 int du[maxn]; 13 struct node 14 { 15 int x,id; 16 bool operator <(const node &a)const 17 { 18 return x<a.x; 19 } 20 } p[maxn]; 21 vector<int>g[maxn]; 22 23 void dfs(int x) 24 { 25 for(int i=0; i<(int)g[x].size(); i++) 26 { 27 printf("%d %d ",x,g[x][i]); 28 dfs(g[x][i]); 29 } 30 } 31 32 int main() 33 { 34 scanf("%d%d",&n,&k); 35 for(int i=1; i<=n; i++) 36 { 37 scanf("%d",&d[i]); 38 p[i].x=d[i]; 39 p[i].id=i; 40 } 41 sort(p+1,p+n+1); 42 if(p[1].x==0&&p[2].x==0||p[1].x!=0) 43 { 44 printf("-1 "); 45 return 0; 46 } 47 int l=1,r=2; 48 int cnt=0; 49 bool flag=false; 50 while(r<=n) 51 { 52 if(p[r].x==p[l].x) 53 { 54 printf("-1 "); 55 return 0; 56 } 57 if(p[r].x-p[l].x==1&&du[p[l].id]<k&&du[p[r].id]<k) 58 { 59 g[p[l].id].push_back(p[r].id); 60 cnt++; 61 du[p[l].id]++; 62 du[p[r].id]++; 63 r++; 64 } 65 else if(p[r].x-p[l].x>1||du[p[l].id]>=k) 66 { 67 l++; 68 if(l==r) 69 { 70 flag=true; 71 break; 72 } 73 } 74 else if(du[p[r].id]>=k) 75 { 76 r++; 77 } 78 else 79 { 80 r++; 81 } 82 } 83 if(flag) 84 { 85 printf("-1 "); 86 return 0; 87 } 88 printf("%d ",cnt); 89 dfs(p[1].id); 90 return 0; 91 }