洛谷 P2323 [HNOI2006]公路修建问题

题目描述

输入输出格式

输入格式:

 

在实际评测时,将只会有m-1行公路

 

输出格式:

 

 

输入输出样例

输入样例#1:
4 2 5
1 2 6 5
1 3 3 1
2 3 9 4
2 4 6 1
3 4 4 2
输出样例#1:
4
2 1
3 2
5 1
输入样例#2:
4 1 5
1 2 6 5
1 3 3 1
2 3 9 4
2 4 6 1
3 4 4 3
输出样例#2:
3
2 1
4 2
5 2

 

坑到炸的一句话、。。

二分+kruskal

屠龙宝刀点击就送

#include <algorithm>
#include <cstdio>
#define N 20005

using namespace std;
struct Edge
{
    int x,y,z,id;
    bool operator<(Edge a)const
    {
        return z<a.z;
    }
}e1[N],e2[N];
struct node
{
    int a,b;
    bool operator<(node x)const
    {
        return a<x.a;
    }
}ans[N];
int n,k,m,siz,fa[N];
int find_(int x) {return x==fa[x]?x:fa[x]=find_(fa[x]);}
bool check(int x)
{
    for(int i=1;i<=n;++i) fa[i]=i;
    int num=0;
    for(int i=1;i<=m;++i)
    {
        if(e1[i].z>x) continue;
        int fx=find_(e1[i].x),fy=find_(e1[i].y);
        if(fx!=fy)
        {
            num++;
            fa[fy]=fx;
        }
    }
    if(num<k) return false;
    for(int i=1;i<=m;++i)
    {
        if(e2[i].z>x) continue;
        int fx=find_(e2[i].x),fy=find_(e2[i].y);
        if(fx!=fy)
        {
            fa[fy]=fx;
            num++;
        }
    }
    if(num==n-1) return true;
    return false;
}
void get(int x)
{
    for(int i=1;i<=n;++i) fa[i]=i;
    for(int i=1;i<=m;++i)
    {
        if(e1[i].z>x) continue;
        int fx=find_(e1[i].x),fy=find_(e1[i].y);
        if(fx!=fy)
        {
            siz++;
            fa[fy]=fx;
            ans[siz].a=e1[i].id;
            ans[siz].b=1;
        }
    }
    for(int i=1;i<=m;++i)
    {
        if(e2[i].z>x) continue;
        int fx=find_(e2[i].x),fy=find_(e2[i].y);
        if(fx!=fy)
        {
            siz++;
            fa[fy]=fx;
            ans[siz].a=e2[i].id;
            ans[siz].b=2;
        }
    }
}
int main(int argc,char *argv[])
{
    scanf("%d%d%d",&n,&k,&m);
    int l=1,r=0,anss;
    for(int u,v,w1,w2,i=1;i<=m;++i)
    {
        scanf("%d%d%d%d",&u,&v,&w1,&w2);
        e1[i]=(Edge){u,v,w1,i};
        e2[i]=(Edge){u,v,w2,i};
        r=max(r,w1); 
    }
    sort(e1+1,e1+m);
    sort(e2+1,e2+m);
    for(int mid;l<=r;)
    {
        mid=(l+r)>>1;
        if(check(mid))
         anss=mid,r=mid-1;
        else l=mid+1;
    }
    printf("%d\n",anss);
    get(anss);
    sort(ans+1,ans+1+siz);
    for(int i=1;i<=siz;++i) printf("%d %d\n",ans[i].a,ans[i].b);
    return 0;
}

 

posted @ 2017-10-17 18:45  杀猪状元  阅读(210)  评论(0编辑  收藏  举报