链接:https://ac.nowcoder.com/acm/contes
链接:https://ac.nowcoder.com/acm/contest/920/A
来源:牛客网
您有一个长度为 n 的数组 ai。请您构造出一张 m 条边的有向图满足 1 号点到 i 号点的最短路长度为数组中的第 i 个数 ai,且要求 m 不超过 10^5 且每条边的长度不超过一个给定的值 s。
一个贪心题
如果每条边都不大于s,那么构造一个菊花图;
如果有边大于s,那么就将边权排序,将每个点都和排序后的前一个点连一条a[i].x-[i-1].x的边。当然如果这条边也大于s的话就不可以了;
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn=5e6+10; int n,s; struct node { int id,x; }a[maxn]; bool cmp(node qw,node we) { return qw.x<we.x; } bool flag=0; int main() { scanf("%d%d",&n,&s); for(int i=1;i<=n;i++) { scanf("%d",&a[i].x);a[i].id=i; if(a[i].x>s) flag=1; } if(flag==0) { for(int i=2;i<=n;i++) { if(!a[i].x) { printf("-1 "); return 0; } } printf("%d ",n-1); for(int i=2;i<=n;i++) { printf("%d %d %d ",1,i,a[i].x); } } else { sort(a+1,a+n+1,cmp); for(int i=2;i<=n;i++) { if(a[i].x-a[i-1].x>s) { printf("-1 "); return 0; } } if(!a[2].x) {printf("-1 ");return 0;} printf("%d ",n-1); int fa=0; for(int i=2;i<=n;i++) { if(a[i].x!=a[i-1].x) fa=i-1; printf("%d %d %d ",a[fa].id,a[i].id,a[i].x-a[fa].x); } } return 0; }