codeforces 545 Round #303 (Div. 2) E Paths and Trees
2015-06-21 16:27
609 查看
求某个顶点的最短路径生成树,且边的总权值最小。如果有多个,输出任意一个即可。(输出最小权值以及所选的边)
选边的时候注意一下:如果u到v,与u到k到v的路径长度相同。应当选取后者。即尽可能经过多的顶点,这样可以保证总权值最小。
选边的时候注意一下:如果u到v,与u到k到v的路径长度相同。应当选取后者。即尽可能经过多的顶点,这样可以保证总权值最小。
#include<bits/stdc++.h> using namespace std; typedef long long LL; #define N 300005 #define inf 0x3f3f3f3f3f3f3f3f struct Edge{ int to,next,id; LL w; }edge[N<<1]; int cnt,n,head ,pre ; LL low ,w ; bool vis ; inline void add(int u,int v,LL w,int id){ edge[cnt].to=v; edge[cnt].w=w; edge[cnt].next=head[u]; edge[cnt].id=id; head[u]=cnt++; } void spfa(int s) { int i,j; memset(vis,0,sizeof(vis)); vis[s]=1,low[s]=0; queue<int> q; q.push(s); while(!q.empty()){ int u=q.front();q.pop(); vis[u]=0; for(i=head[u];~i;i=edge[i].next){ int v=edge[i].to; if(low[v]>low[u]+edge[i].w){ low[v]=low[u]+edge[i].w; pre[v]=edge[i].id; if(!vis[v]){ vis[v]=1; q.push(v); } } else if(low[v]==low[u]+edge[i].w){ if(w[pre[v]]>edge[i].w){ pre[v]=edge[i].id; if(!vis[v]){ vis[v]=1; q.push(v); } } } } } } int main() { int m,i,u; scanf("%d%d",&n,&m); memset(low,inf,sizeof(low)); memset(head,-1,sizeof(head)); for(i=1;i<=m;++i){ int x,y; LL z; scanf("%d%d%lld",&x,&y,&z); add(x,y,z,i); add(y,x,z,i); w[i]=z; } scanf("%d",&u); spfa(u); LL s=0; for(i=1;i<=n;++i) if(pre[i]) s+=w[pre[i]]; printf("%lld\n",s); for(i=1;i<=n;++i) if(pre[i]) printf("%d ",pre[i]); puts(""); return 0; }
相关文章推荐
- Valid Palindrome
- log4net:保存日志到数据库
- UIAlertView
- Python os模块学习笔记
- HDU 5273(暴力前缀和)
- iOS学习009
- Android计时器
- UIActivityIndicatorView
- swift 传值 引用 (=、&)
- 第21题:求1~n序列中等于m的所有组合
- python中动态加载模块和类方法实现
- CustomPickerView
- CEF简介
- YT04-贪心课后练习-1006—PAINTER(6.14日-烟台大学ACM预备队解题报告)
- swipe.js 2.0 轻量级框架实现mobile web 左右滑动
- UIpickerView
- 初学Vim编辑器基础操作总结
- 关于MPLS和Vlan隔离技术的思考
- JVM 字节码指令对于栈帧数据操作举例
- cin、cin.get()、cin.getline()、getline()、gets()等函数的用法