CodeForces 605B Lazy Student

构造。对边的权值排序,权值一样的话,在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
");
                        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
",e[i].u,e[i].v);
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/zufezzt/p/5049394.html