3624: [Apio2008]免费道路
Time Limit: 2 Sec Memory Limit: 128 MBSec Special JudgeSubmit: 921 Solved: 371
[ Submit][ Status][ Discuss]
Description
Input
Output
Sample Input
5 7 2
1 3 0
4 5 1
3 2 0
5 3 1
4 3 0
1 2 1
4 2 1
1 3 0
4 5 1
3 2 0
5 3 1
4 3 0
1 2 1
4 2 1
Sample Output
3 2 0
4 3 0
5 3 1
1 2 1
4 3 0
5 3 1
1 2 1
HINT
Source
先把所有边排序,优先选择水泥路,这样做最小生成树
这样得到的这棵树,这其中的鹅卵石路显然是一定得存在于答案中
如果这个数目太大,当然no solution
重新建树,先把一定需要的鹅卵石路算上
然后优先选择鹅卵石路,搞到刚好k条,如果可以,那就有解
这样做显然是对的,因为只要能新增鹅卵石路,那么就相当于在原树中删掉一条水泥路
#include<iostream>
#include<cstdio>
#include<queue>
#include<vector>
#include<bitset>
#include<algorithm>
#include<cstring>
#include<map>
#include<stack>
#include<set>
#include<cmath>
#include<ext/pb_ds/priority_queue.hpp>
using namespace std;
const int maxn = 1E5 + 10;
struct E{
int x,y,typ;
E(){}
E(int x,int y,int typ): x(x),y(y),typ(typ){}
bool operator < (const E &b) const {
return typ > b.typ;
}
}edgs[maxn];
int n,m,k,fa[maxn];
bool Mark[maxn],Ans[maxn];
int getfa(int x) {return x == fa[x]?x:fa[x] = getfa(fa[x]);}
int getint()
{
char ch = getchar();
int ret = 0;
while (ch < '0' || '9' < ch) ch = getchar();
while ('0' <= ch && ch <= '9')
ret = ret*10 + ch - '0',ch = getchar();
return ret;
}
int main()
{
#ifdef DMC
freopen("DMC.txt","r",stdin);
#endif
n = getint();
m = getint();
k = getint();
for (int i = 1; i <= m; i++) {
int x = getint();
int y = getint();
int typ = getint();
edgs[i] = E(x,y,typ);
}
sort(edgs + 1,edgs + m + 1);
for (int i = 1; i <= n; i++) fa[i] = i;
int tot = 0;
for (int i = 1; i <= m; i++) {
int fx = getfa(edgs[i].x);
int fy = getfa(edgs[i].y);
if (fx != fy) {
fa[fx] = fy;
if (!edgs[i].typ) ++tot;
Mark[i] = 1;
}
}
if (tot > k) {
puts("no solution");
return 0;
}
if (tot == k) {
for (int i = 1; i <= m; i++)
if (Mark[i])
printf("%d %d %d\n",edgs[i].x,edgs[i].y,edgs[i].typ);
return 0;
}
for (int i = 1; i <= n; i++) fa[i] = i;
for (int i = 1; i <= m; i++)
if (Mark[i] && !edgs[i].typ) {
int fx = getfa(edgs[i].x);
int fy = getfa(edgs[i].y);
fa[fx] = fy;
Ans[i] = 1;
}
for (int i = 1; i <= m; i++)
if (!edgs[i].typ && !Mark[i]) {
int fx = getfa(edgs[i].x);
int fy = getfa(edgs[i].y);
if (fx != fy) {
fa[fx] = fy;
++tot;
Ans[i] = 1;
}
if (tot == k) break;
}
if (tot < k) {
puts("no solution");
return 0;
}
for (int i = 1; i <= m; i++) {
int fx = getfa(edgs[i].x);
int fy = getfa(edgs[i].y);
if (fx != fy) {
fa[fx] = fy;
Ans[i] = 1;
}
}
for (int i = 1; i <= m; i++)
if (Ans[i])
printf("%d %d %d\n",edgs[i].x,edgs[i].y,edgs[i].typ);
return 0;
}