UVA-10600-ACM Contest and Blackout (次小生成树三种解法)
来源:互联网 发布:ubuntu如何卸载wine 编辑:程序博客网 时间:2024/06/07 07:45
题目链接:UVA-10600-ACM Contest and Blackout
次小生成树有两种算法,一种是先跑一次最小生成树并记录下每条边,然后每次仅删去一条边,跑n-1次最小生成树取最小值为次小生成树,这样的时间复杂度是O(
还有一种就是跑一次最小生成树的过程中得到
有一个结论是:设最小生成树为
有了
枚举所有边后的权值最小值就是次小生成树权值了。
时间复杂度是,是
邻接矩阵:
#include<bits/stdc++.h>using namespace std;const int INF=0x3f3f3f3f;int G[107][107],pre[107],d[107],Max[107][107],n,m;bool vis[107],gvis[107][107];int Prim(int &min1,int &min2){ min1=0;min2=INF; memset(vis,0,sizeof(vis)); memset(Max,0,sizeof(Max)); memset(d,0x3f,sizeof(d)); memset(gvis,0,sizeof(gvis)); for(int i=2;i<=n;i++) if(G[1][i]!=INF) { d[i]=G[1][i]; pre[i]=1; } vis[1]=true; for(int i=1;i<n;i++) { int u,c=INF; for(int j=1;j<=n;j++) { if(vis[j]) continue; if(d[j]<c) c=d[j],u=j; } gvis[pre[u]][u]=gvis[u][pre[u]]=true; min1+=c; for(int v=1;v<=n;v++) if(vis[v]) Max[u][v]=Max[v][u]=max(Max[v][pre[u]],c); vis[u]=true; for(int j=1;j<=n;j++) { if(vis[j]) continue; if(G[u][j]<d[j]) { d[j]=G[u][j]; pre[j]=u; } } } for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { if(G[i][j]!=INF&&!gvis[i][j]) min2=min(min2,min1+G[i][j]-Max[i][j]); } }}int main(){ int T; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); int u,v,c; memset(G,0x3f,sizeof(G)); for(int i=0;i<m;i++) { scanf("%d%d%d",&u,&v,&c); G[u][v]=G[v][u]=c; } int min1,min2; Prim(min1,min2); printf("%d %d\n",min1,min2); } return 0;}
堆优化:
#include<vector>#include<iostream>#include<algorithm>#include<cstdio>#include<cstring>#include<queue>using namespace std;int d[107],Max[107][107],n,m,G[107][107];bool vis[107];struct Edge{ int u,v,d; Edge(int _u,int _v,int _d):u(_u),v(_v),d(_d){} Edge(){} bool operator < (const Edge & r) const { return d>r.d; }};vector<Edge> adj[107];void Prim(int &min1,int &min2){ memset(vis,0,sizeof(vis)); min1=0; min2=0x3f3f3f3f; priority_queue<Edge> q; q.push(Edge(1,1,0)); memset(Max,0,sizeof(Max)); memset(G,0,sizeof(G)); while(!q.empty()) { Edge t=q.top();q.pop(); if(vis[t.v]) continue; min1+=t.d; G[t.u][t.v]=G[t.v][t.u]=true; for(int i=1;i<=n;i++) if(vis[i]) Max[i][t.v]=Max[t.v][i]=max(Max[t.u][i],t.d); vis[t.v]=true; for(int i=0;i<adj[t.v].size();i++) { Edge e=adj[t.v][i]; if(vis[e.v]) continue; q.push(e); } } for(int i=1;i<=n;i++) { for(int j=0;j<adj[i].size();j++) { Edge t=adj[i][j]; if(G[i][t.v]) continue; min2=min(min2,min1-Max[t.u][t.v]+t.d); } }}int main(){ ios::sync_with_stdio(false);cin.tie(0); int T; cin>>T; while(T--) { cin>>n>>m; int u,v,c; for(int i=1;i<=n;i++) adj[i].clear(); memset(G,0,sizeof(G)); for(int i=0;i<m;i++) { cin>>u>>v>>c; adj[u].push_back(Edge(u,v,c)); adj[v].push_back(Edge(v,u,c)); } int min1,min2; Prim(min1,min2); cout << min1 << " " << min2 << endl; } return 0;}
0 0
- UVA-10600-ACM Contest and Blackout (次小生成树三种解法)
- UVA 10600 - ACM Contest and Blackout 次小生成树
- 【UVa】10600 ACM Contest and Blackout 次小生成树
- uva 10600 ACM Contest and Blackout(次小生成树)
- UVA 10600 ACM Contest and Blackout (次小生成树)
- UVA - 10600 ACM Contest and Blackout(次小生成树)
- Uva 10600 ACM Contest and Blackout(次小生成树)
- UVA 10600 - ACM Contest and Blackout(最小生成树&次小生成树)
- UVa 10600 ACM contest and Blackout( 次小生成树)
- uva 10600 - ACM Contest and Blackout(次小生成树)
- UVA 10600 - ACM Contest and Blackout (次小生成树)
- UVA 10600 - ACM Contest and Blackout(次小生成树)
- UVA 10600 ACM Contest and Blackout(次小生成树)
- uva 10600 ACM Contest and Blackout (次小生成树)
- uva 10600 - ACM Contest and Blackout(次小生成树)
- UVA 10600 ACM Contest and Blackout(最小生成树and次小生成树)
- UVA 10600 ACM Contest and Blackout 次小生成树/裸
- UVA 10600 ACM Contest and Blackout (次小生成树 Kruskal 封装)
- HBase phoenix二级索引
- Get Docker for Debian or Raspbian
- 201503-2
- java琐碎的知识点
- 教你几个轻松激活win7的方法
- UVA-10600-ACM Contest and Blackout (次小生成树三种解法)
- python的requests包的安装
- IE浏览器引用css样式表的方法
- rabbitmq学习4:Routing
- java问题排查工具单
- maven可以编译但启动找不到类
- 最好用的 iOS 快速布局UI库
- SpringMVC:No mapping found for HTTP request with URI [/account/*] in DispatcherServlet with
- 在Blender中通过法线贴图和顶点位移实现石块地面的凹凸感