bzoj 3624: [Apio2008]免费道路(并查集+生成树+乱搞)
来源:互联网 发布:重叠覆盖优化案例 编辑:程序博客网 时间:2024/06/06 11:39
3624: [Apio2008]免费道路
Time Limit: 2 Sec Memory Limit: 128 MBSec Special JudgeSubmit: 727 Solved: 300
[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
这道题就是求一颗生成树,使特殊边的条数恰好为k 。
那么我们可以把所有非特殊边先加进去,用并查集把所有联通块并在一起,然后开始加特殊边,看是否存在必须加的特殊边(即不加这条边之前这两个点不连通)。
然后我们重新构建生成树,先把所以的必须加的特殊边加进去,然后在加特殊边直到K条,最后再加非特殊边,保证是颗树即可。
注意各种无解的情况,小心处理即可。
#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#define N 20003#define M 100003using namespace std;int n,m,k;int u[M],v[M],c[M];int cnt,x[M],y[M],fa[N],vis[M],belong[M],x1[M],yy[M],c1[M];int find(int x){if (fa[x]==x) return x;fa[x]=find(fa[x]);return fa[x];}int main(){scanf("%d%d%d",&n,&m,&k);for (int i=1;i<=m;i++) scanf("%d%d%d",&u[i],&v[i],&c[i]);for (int i=1;i<=n;i++) fa[i]=i;for (int i=1;i<=m;i++) if (c[i]&&find(u[i])!=find(v[i])) { int r1=find(u[i]); int r2=find(v[i]); fa[r2]=r1; }for (int i=1;i<=m;i++) if (!c[i]&&find(u[i])!=find(v[i])) { cnt++; vis[m]=1;x[cnt]=u[i]; y[cnt]=v[i]; belong[cnt]=c[i];int r1=find(u[i]); int r2=find(v[i]); fa[r2]=r1; }int t=find(1);for (int i=2;i<=n;i++) if (find(i)!=t) { printf("no solution\n"); return 0; }for (int i=1;i<=n;i++) fa[i]=i;if (cnt>k) {printf("no solution\n");return 0;}int num=0; int tot=0;for (int i=1;i<=cnt;i++) { int r1=find(x[i]); int r2=find(y[i]); fa[r2]=r1; num++; tot++; x1[tot]=x[i]; yy[tot]=y[i]; c1[tot]=belong[i]; }for (int i=1;i<=m;i++) if (!c[i]&&find(u[i])!=find(v[i])) { int r1=find(u[i]); int r2=find(v[i]); fa[r2]=r1; num++; tot++; x1[tot]=u[i]; yy[tot]=v[i]; c1[tot]=c[i]; if (tot==k) break; }if (tot!=k) {printf("no solution\n");return 0;}for (int i=1;i<=tot;i++) printf("%d %d %d\n",x1[i],yy[i],c1[i]);for (int i=1;i<=m;i++) if (c[i]&&find(u[i])!=find(v[i])) { printf("%d %d %d\n",u[i],v[i],c[i]); int r1=find(u[i]); int r2=find(v[i]); fa[r2]=r1; num++; if (num==n-1) break; }}
0 0
- bzoj 3624: [Apio2008]免费道路(并查集+生成树+乱搞)
- [BZOJ 3624][Apio2008]免费道路:最小生成树
- [BZOJ]3624: [Apio2008]免费道路 最小生成树
- [BZOJ3624][Apio2008]免费道路(贪心+并查集)
- [BZOJ3624][Apio2008]免费道路(并查集)
- 【BZOJ3624】【APIO2008】免费道路(贪心+并查集)
- APIO2008免费道路 Bsoj2714 并查集+两次最小生成树
- 【bzoj 3624】: [Apio2008]免费道路
- bzoj 3624: [Apio2008]免费道路
- 【BZOJ】【P3624】【Apio2008】【免费道路】【题解】【生成树】
- 【bzoj3624】[Apio2008]免费道路 贪心+并查集
- 【并查集】【生成树】【APIO 2008】【bzoj 3624】免费道路
- BZOJ 3264 [Apio2008]免费道路
- BZOJ P3624[Apio2008]免费道路
- 3624: [Apio2008]免费道路
- 3624: [Apio2008]免费道路
- 【APIO2008T2】免费道路-并查集+生成树
- BZOJ3624 [Apio2008]免费道路
- 建立领域模型
- 一个IO传奇的一生-1
- C++之数组
- Java数组预处理实现费切那波数列
- javascript之DOM编程增加附件
- bzoj 3624: [Apio2008]免费道路(并查集+生成树+乱搞)
- 栈内存与堆内存与排序
- 设计模式之单例模式
- bitbake简单的helloworld expamle
- SAP Web IDE - sapui5开发工具
- 二叉搜索树
- KMP
- 按位与、或、异或等运算方法
- 杭电1995