CodeForces 605 B.Lazy Student(构造)
2017-04-20 10:59
351 查看
Description
给出一个n个点m条边的图的每条边的边权和该条边是否是这张图的最小生成树的树边,问满足这些条件的图是否存在,如果存在则输出这张图,否则输出-1
Input
第一行输入两个整数n和m表示点数和边数,之后m行每行两个整数ai和bi分别表示第i条边的边权和第i条边是否是最小生成树的树边(2<=n<=1e5,1<=m<=1e5,n-1<=m<=n*(n-1)/2,1<=ai<=1e9)
Output
如果存在满足条件的图则按输入的边权顺序输出对应的边,否则输出-1
Sample Input
4 5
2 1
3 1
4 0
1 1
5 0
Sample Output
2 4
1 4
3 4
3 1
3 2
Solution
构造题,考虑求MST的过程,一条边u->v被淘汰是因为已经找到的MST集合中u->v已经通过边权更小的边可达了,那么在此题的构造中,我们先用给出的n-1条树边构造出一棵MST,然后看剩下的m-n+1条边是否能够通过合理的放置让其在求MST的过程中被淘汰,为使得这n-1条树边起到充分的作用,我们构造一个星型树,即1点分别连向2,3,…,n点形成一棵树,且1-2,1-3,…,1-n的边权递增,对于非树边,我们降序排,贪心的处理边权较大的边,因为边权较大的边不先处理掉的话一些树边的作用可能会被一些边权小的非树边浪费,每次以pos点为终点,起点s从2开始,pos点需满足边1-pos的权不大于当前要插入的边的权w,这样以来把w作为边权赋给s-pos边在求MST时必然会被1-pos边淘汰,每次s=pos时就令pos=pos-1换个终点,然后起点接着从2开始,如果终点也是2了说明当前处理的非树边无法通过树边淘汰掉了,进而无解。
注意到给树边和非树边分别排好序的主要好处就是用游标法优化了每次找pos的过程,时间复杂度O(mlogm)
Code
给出一个n个点m条边的图的每条边的边权和该条边是否是这张图的最小生成树的树边,问满足这些条件的图是否存在,如果存在则输出这张图,否则输出-1
Input
第一行输入两个整数n和m表示点数和边数,之后m行每行两个整数ai和bi分别表示第i条边的边权和第i条边是否是最小生成树的树边(2<=n<=1e5,1<=m<=1e5,n-1<=m<=n*(n-1)/2,1<=ai<=1e9)
Output
如果存在满足条件的图则按输入的边权顺序输出对应的边,否则输出-1
Sample Input
4 5
2 1
3 1
4 0
1 1
5 0
Sample Output
2 4
1 4
3 4
3 1
3 2
Solution
构造题,考虑求MST的过程,一条边u->v被淘汰是因为已经找到的MST集合中u->v已经通过边权更小的边可达了,那么在此题的构造中,我们先用给出的n-1条树边构造出一棵MST,然后看剩下的m-n+1条边是否能够通过合理的放置让其在求MST的过程中被淘汰,为使得这n-1条树边起到充分的作用,我们构造一个星型树,即1点分别连向2,3,…,n点形成一棵树,且1-2,1-3,…,1-n的边权递增,对于非树边,我们降序排,贪心的处理边权较大的边,因为边权较大的边不先处理掉的话一些树边的作用可能会被一些边权小的非树边浪费,每次以pos点为终点,起点s从2开始,pos点需满足边1-pos的权不大于当前要插入的边的权w,这样以来把w作为边权赋给s-pos边在求MST时必然会被1-pos边淘汰,每次s=pos时就令pos=pos-1换个终点,然后起点接着从2开始,如果终点也是2了说明当前处理的非树边无法通过树边淘汰掉了,进而无解。
注意到给树边和非树边分别排好序的主要好处就是用游标法优化了每次找pos的过程,时间复杂度O(mlogm)
Code
#include<cstdio> #include<algorithm> using namespace std; #define maxn 111111 int n,m; struct node { int w,flag,id,u,v; bool operator<(const node &b)const { if(flag!=b.flag)return flag>b.flag; if(flag)return w<b.w; return w>b.w; } }a[maxn]; bool cmp(node a,node b) { return a.id<b.id; } int main() { while(~scanf("%d%d",&n,&m)) { for(int i=1;i<=m;i++) { scanf("%d%d",&a[i].w,&a[i].flag); a[i].id=i; } sort(a+1,a+m+1); for(int i=1;i<n;i++) a[i].u=1,a[i].v=i+1; int gg=0; int pos=n; while(pos>=3&&a[pos-1].w>a .w)pos--; for(int i=n,j=pos,k=2;i<=m;i++) { if(j==2) { gg=1; break; } while(a[i].w<a[j-1].w) { j--,k=2; if(j==2) { gg=1; break; } } if(k==j)j--,k=2; if(j==k) { gg=1; break; } a[i].u=k++,a[i].v=j; } if(gg)printf("-1\n"); else { sort(a+1,a+m+1,cmp); for(int i=1;i<=m;i++)printf("%d %d\n",a[i].u,a[i].v); } } return 0; }
相关文章推荐
- cf 605B B. Lazy Student 构造 好题
- Codeforces 605B 构造
- 【Codeforces Round 335 (Div 2) D】【构造 脑洞】Lazy Student 图的最小生成树告诉边权和选取情况让你还原图
- [CodeForces 605B]Lazy Student[贪心][构造]
- Codeforces Round #335 (Div. 2) D. Lazy Student 构造
- CF 335 div.1-B/div.2-D/605 B Lazy Student
- Codeforces Round #335 (Div. 2) D. Lazy Student 贪心+构造
- Codeforces Round 335 (Div 2) D. Lazy Student【构造 脑洞 最小生成树】
- Codeforces 606 D Lazy Student【逆最小生成树+思维】好题
- CodeForces - 848A From Y to Y(构造)
- Codeforces 798D Mike and distribution 构造
- CodeForces - 743C Vladik and fractions (构造 找规律)
- codeforces 740C mex 构造
- Codeforces 482 - Diverse Permutation 构造题
- CodeForces 66D - Petya and His Friends(构造)
- codeforces 487 C Prefix Product Sequence 构造+逆元
- codeforces 201A A. Clear Symmetry(数论+构造)
- CodeForces 652B z-sort(构造)
- Codeforces 483C Diverse Permutation【思维构造】
- Codeforces 583C GCD Table 【gcd + 构造】