[Luogu2323] [HNOI2006]公路修建问题

题目描述

输入输出格式

输入格式:

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

输出格式:

输入输出样例

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




简单的贪心,




#include <iostream> 
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
 
int n, k, m;
 
struct edge
{
    int x, y;
    int val;
    int v1, v2;
    int yuan;
}ed[20005];
int cnt;
int l = 1, r , mid;
 
void add(int x, int y, int z, int zz, int zzz)
{
    cnt++;
    ed[cnt].x = x;
    ed[cnt].y = y;
    ed[cnt].val = min(z, zz);
    ed[cnt].v1 = z;// er ji 
    ed[cnt].v2 = zz; // yi ji
    ed[cnt].yuan = zzz;
}
 
int fa[10005];
 
int Find(int x)
{
    return x == fa[x] ? x : fa[x] = Find(fa[x]);
}
 
bool use[20005][2];
 
bool cmp1(edge a, edge b)
{
    if (a.v2 == b.v2) return a.v1 < b.v1;
    return a.v2 < b.v2;
}

inline bool cmp2(edge a, edge b)
{
    return a.val < b.val;
}
 
int ans = 0;
 
 
int main()
{
    cin >> n >> k >> m;
     
    for(register int i = 1 ; i < m ; i ++)
    {
        int x, y, z, zz;
        scanf("%d%d%d%d", &x, &y, &z, &zz);
        add(x, y, zz, z, i);
        r = max(r, max(z, zz));
    }
    
    int ans = 0;
    
    sort(ed + 1, ed + cnt + 1, cmp1);
    
    for (register int i = 1 ; i <= n ; i ++) fa[i] = i;
    
    int num = 0;
    for (register int i = 1 ; i <= cnt ; i ++)
    {
        if (num == k) break;
        int x = ed[i].x, y = ed[i].y;
        int fx = Find(x), fy = Find(y);
        if (fx == fy) continue;
        ans = max(ans, ed[i].v2);
        fa[fx] = fy;
        num++;
        use[ed[i].yuan][0] = 1;
    }
    sort(ed + 1, ed + cnt + 1, cmp2);
    for (int i = 1 ; i <= cnt ; i ++)
    {
          if (num == n - 1) break;
        int x = ed[i].x, y = ed[i].y;
        int fx = Find(x), fy = Find(y);      
        if (fx == fy) continue;
        if (use[ed[i].yuan][0]) continue;
        ans = max(ans, ed[i].val);
        fa[fx] = fy;
        num++;
        if (ed[i].val == ed[i].v2) use[ed[i].yuan][0] = 1;
        if (ed[i].val == ed[i].v1) use[ed[i].yuan][1] = 1;
          if (num == n - 1) break;
    }
    cout << ans << endl;
    for (int i = 1 ; i <= cnt ; i ++) 
    {
        if (use[i][0]) printf("%d %d
", i, 1);
        else if (use[i][1]) printf("%d %d
", i, 2);
    }
     
    return 0;
}
原文地址:https://www.cnblogs.com/BriMon/p/9602965.html