洛谷 P3366 【模板】最小生成树
2017-10-17 20:42
351 查看
题目描述
如题,给出一个无向图,求出最小生成树,如果该图不连通,则输出 orz输入输出格式
输入格式:
第一行包含两个整数N、M,表示该图共有 N 个结点和 M 条无向边。(N≤5000,M≤200000)接下来 M 行每行包含三个整数 Xi、Yi、Zi,表示有一条长度为 Zi 的无向边连接结点Xi、Yi
输出格式:
输出包含一个数,即最小生成树的各边的长度之和;如果该图不连通则输出 orz输入输出样例
输入样例#1:
4 5 1 2 2 1 3 2 1 4 3 2 3 4 3 4 3
输出样例#1:
7
说明
时空限制:
1000ms,128M
数据规模:
对于20%的数据:N≤5,M≤20对于40%的数据:N≤50,M≤2500
对于70%的数据:N≤500,M≤10000
对于100%的数据:N≤5000,M≤200000
样例解释:
所以最小生成树的总边权为2+2+3=7
solution
对于n≤1000的数据,Prim模板题其余的数据,Kruskal模板题
code
其实还想写堆优化的prim来着,但是没找到代码风格和我差不多的模板…sad就先用这两个吧
还有一遍速度对比的文章,感兴趣的话可以戳这里
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; typedef long long ll; template<typename T> void input(T &x) { x=0; T a=1; register char c=getchar(); for(;c<'0'||c>'9';c=getchar()) if(c=='-') a=-1; for(;c>='0'&&c<='9';c=getchar()) x=x*10+c-'0'; x*=a; return; } namespace __Prim { const int MAXN=1000; const int inf=2147483647; int G[MAXN][MAXN]; int lowcost[MAXN]; bool vis[MAXN]; void Prim(int n,int m) { for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) G[i][j]=inf*(i!=j); for(int i=1;i<=m;i++) { int u,v,w; input(u),input(v),input(w); if(w<G[u][v]) G[u][v]=w; if(w<G[v][u]) G[v][u]=w; } for(int i=1;i<=n;i++) lowcost[i]=G[1][i],vis[i]=false; vis[1]=true; int MST=0; for(int k=1;k<n;k++) { int Min=inf,u=-1; for(int i=1;i<=n;i++) if(!vis[i]&&lowcost[i]<Min) Min=lowcost[u=i]; if(u==-1) { printf("orz"); return; } vis[u]=true; MST+=Min; for(int v=1;v<=n;v++) if(!vis[v]&&lowcost[v]>G[u][v]) lowcost[v]=G[u][v]; } printf("%d",MST); return; } } namespace __Kruskal { const int MAXN=5010; const int MAXM=200010; struct Edge { int u,v,w; Edge(int u=0,int v=0,int w=0): u(u),v(v),w(w) {} bool operator < (const Edge &q) const { return w<q.w; } }; Edge edge[MAXM]; int father[MAXN]; int Find(int x) { return father[x]==x?x:father[x]=Find(father[x]); } bool Union(int x,int y) { if((x=Find(x))==(y=Find(y))) return false; father[x]=y; return true; } void Kruskal(int n,int m) { for(int i=1;i<=m;i++) input(edge[i].u), input(edge[i].v), input(edge[i].w); for(int i=1;i<=n;i++) father[i]=i; sort(edge+1,edge+m+1); int MST=0,k=0; for(int i=1;i<=m;i++) if(Union(edge[i].u,edge[i].v)) MST+=edge[i].w,k++; if(k==n-1) printf("%d",MST); else printf("orz"); return; } } int main() { int n,m; input(n),input(m); if(n<=1000) __Prim::Prim(n,m); else __Kruskal::Kruskal(n,m); return 0; }
相关文章推荐
- 洛谷P3366 【模板】最小生成树
- 洛谷 P3366 【模板】最小生成树
- P3366 最小生成树【模板】 洛谷
- 洛谷P3366 【模板】最小生成树
- 洛谷——P3366 【模板】最小生成树
- 洛谷 P3366 【模板】最小生成树
- 洛谷 P3366 【模板】最小生成树
- 洛谷3366 最小生成树模板题
- P3366 【模板】最小生成树
- 洛谷——最小生成树模板
- P3366 【模板】最小生成树
- 最小生成树(模板)洛谷3366
- P3366 【模板】最小生成树
- [洛谷3366]【模板】最小生成树
- P3366 【模板】最小生成树
- 洛谷 [模板]最小生成树
- P3366 【模板】最小生成树
- HDU1102-Constructing Roads-最小生成树(prim模板题)
- 最小生成树模板(poj3625)
- 图论——最小生成树Kruskal算法模板