构造。对边的权值排序,权值一样的话,在MST中的边排到前面,否则权值小的排在前面。
然后边一条一条扫过去,如果是1 ,那么连一个点到集合中,如果是0,集合内的边相连。
#include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std; const int maxn=100000+10; struct Edge { int u,v; int w; int info; int id; } e[maxn]; int n,m; int flag; int last[maxn]; int K; int now; bool cmp(const Edge&a,const Edge&b) { if(a.w==b.w) return a.info>b.info; return a.w<b.w; } bool cmp2(const Edge&a,const Edge&b) { return a.id<b.id; } void init() { now=1; flag=0; K=2; for(int i=1; i<=n; i++) last[i]=i; } int main() { while(~scanf("%d%d",&n,&m)) { init(); for(int i=1; i<=m; i++) { scanf("%d%d",&e[i].w,&e[i].info); e[i].id=i; } sort(e+1,e+m+1,cmp); for(int i=1; i<=m; i++) { if(e[i].info==1) { e[i].u=1; now++; e[i].v=now; K=2; } else if(e[i].info==0) { while(1) { if(K>=now+1) { printf("-1\n"); flag=1; break; } if(last[K]+1<=now) { e[i].u=K; e[i].v=last[K]+1; last[K]++; break; } else K++; } } if(flag) break; } sort(e+1,e+m+1,cmp2); if(flag==0) { for(int i=1; i<=m; i++) printf("%d %d\n",e[i].u,e[i].v); } } return 0; }
时间: 2024-10-03 14:56:15