题目描述
输入输出格式
输入格式:
在实际评测时,将只会有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; }