UVAlive 6622 Absurdistan Roads(最小生成树+LCA)
来源:互联网 发布:用友软件电话 编辑:程序博客网 时间:2024/05/24 05:42
题目地址:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4633
思路:每个点之间连边,权值为两点之间的最短距离。则该图的最小生成树的n-1条边在最终的n条边内。则两点(i,j)之间距离为dist[i]+dist[j]-2*dist[ LCA(i,j) ](dist[i]表示根节点(设为1)到i节点的距离)。若树上每点之间的距离都不大于每点之间的最短距离,则只需任意添加一条边即可。否则,选择不符合条件但权值最小的边,添加(题目保证有解,不符合条件的两点需要走树上的边和该条边,则该条边权值越小越能保证满足条件)。
#include<queue>#include<vector>#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#define debuusing namespace std;const int maxn=4050;const int INF=0x3f3f3f3f;struct Edge{ int u,v,w; Edge(int u=0,int v=0,int w=0):u(u),v(v),w(w) {}};struct Node{ int p,w; Node(int p=0,int w=0):p(p),w(w) {}};int n,cas=0;queue<int> q;vector<Edge> e;int dist[maxn];vector<Edge> ans;int anc[maxn][50];int v[maxn],V[maxn];int mat[maxn][maxn];int tree[maxn][maxn];int fa[maxn],d[maxn];vector<Node> g[maxn];int cmp(Edge a,Edge b){ return a.w<b.w;}int Find(int x){ return fa[x]==x?x:fa[x]=Find(fa[x]);}void init(){ e.clear(); ans.clear(); memset(v,0,sizeof(v)); memset(d,0,sizeof(d)); memset(V,0,sizeof(V)); memset(anc,0,sizeof(anc)); memset(tree,0,sizeof(tree)); for(int i=1; i<=n; i++) { fa[i]=i; g[i].clear(); }}void build(){ int tot=0; sort(e.begin(),e.end(),cmp); //cout<<"*************"<<endl; for(int i=0; i<e.size(); i++) { int x=e[i].u,y=e[i].v,w=e[i].w; //cout<<x<<" "<<y<<" "<<w<<endl; int xx=Find(x),yy=Find(y); if(xx!=yy) { fa[xx]=yy; g[x].push_back(Node(y,w)); g[y].push_back(Node(x,w)); ans.push_back(Edge(x,y,w)); //cout<<x<<" "<<y<<" "<<w<<endl; tree[x][y]=tree[y][x]=1; //cout<<x<<" "<<y<<" "<<w<<endl; if(++tot==n-1) break; } }}void dfs(int x,int dep){ v[x]=1,d[x]=dep; for(int i=0; i<g[x].size(); i++) { int nt=g[x][i].p; if(!v[nt]) { anc[nt][0]=x; int k=0; while(anc[anc[nt][k]][k]!=0) { anc[nt][k+1]=anc[anc[nt][k]][k]; k++; } dfs(nt,dep+1); } }}int LCA(int x,int y){ if(d[x]<d[y]) swap(x,y); int l=d[x]-d[y]; int k=0,ans=INF; while(l!=0) { if(l&1) { x=anc[x][k]; } l>>=1; k++; } k=0; while(x!=y) { if((anc[x][k]!=anc[y][k])||(!k)) { x=anc[x][k],y=anc[y][k]; k++; } else k--; } return x;}void bfs(){ memset(V,0,sizeof(V)); while(!q.empty()) q.pop(); for(int i=1; i<=n; i++) dist[i]=INF; V[1]=1,q.push(1),dist[1]=0; while(!q.empty()) { int now=q.front(); q.pop(); for(int i=0; i<g[now].size(); i++) { int nt=g[now][i].p; if(V[nt]) continue; dist[nt]=min(dist[nt],dist[now]+g[now][i].w); V[nt]=1,q.push(nt); } }}void solve(){ for(int i=1; i<=n; i++) if(!v[i]) dfs(i,0); int flag=0,mind=INF,u,v; for(int i=1; i<=n; i++) for(int j=i+1; j<=n; j++) { //cout<<i<<" "<<j<<" "<<LCA(i,j)<<endl; int mindist=dist[i]+dist[j]-2*dist[LCA(i,j)]; if(mindist>mat[i][j]) { flag=1; if(mat[i][j]<mind) { mind=mat[i][j]; u=i,v=j; } } } if(!flag) { ans.push_back(Edge(1,2,mat[1][2])); } else { ans.push_back(Edge(u,v,mind)); }}int main(){#ifdef debug freopen("in.in","r",stdin);#endif // debug while(scanf("%d",&n)!=EOF) { init(); for(int i=1; i<=n; i++) for(int j=1; j<=n; j++) { scanf("%d",&mat[i][j]); if(i!=j) e.push_back(Edge(i,j,mat[i][j])); } build(); bfs(); solve(); cas++; if(cas!=1) printf("\n"); for(int i=0; i<ans.size(); i++) printf("%d %d %d\n",ans[i].u,ans[i].v,ans[i].w); } return 0;}
0 0
- UVAlive 6622 Absurdistan Roads(最小生成树+LCA)
- UVALive 6622 Absurdistan Roads
- nwerc2013 A-Absurdistan Roads (最小生成树(kruskal)+最短路(floyd))
- Constructing Roads(最小生成树)
- hdoj_1102Constructing Roads(最小生成树)&& poj_2485Highways
- Jungle Roads(最小生成树)
- HDU1102 Constructing Roads(最小生成树)
- HDU1102 Constructing Roads(最小生成树)
- hdoj1102_Constructing Roads(最小生成树)
- hdoj Constructing Roads(最小生成树)
- Constructing Roads(最小生成树)
- poj2421Constructing Roads(最小生成树)
- Constructing Roads (最小生成树 Kruskal)
- POJ11251---Jungle Roads(最小生成树)
- Roads and Libraries(最小生成树)
- Jungle Roads 最小生成树(kruskal)
- Constructing Roads (最小生成树)
- Building Roads(prim 最小生成树)
- Libev官方在线API 网址
- leetcode Jump Game
- FZU 2216 The Longest Straight (二分)
- hdu 5861Road(2016 Multi-University Training Contest 10——线段树+扫描线)
- 变频无线发射机系统电路设计详解
- UVAlive 6622 Absurdistan Roads(最小生成树+LCA)
- JavaWeb 分页
- 【软件工程】--需求分析
- 直方图均衡化
- Ubuntu快速安装jdk 1.8
- js代码执行C#代码
- jvm面试题(三)
- JS组件系列——封装自己的JS组件,你也可以
- poj 3273 Monthly Expense