BZOJ 1726 [Usaco2006 Nov]Roadblocks第二短路
2017-04-09 21:14
375 查看
Description
贝茜把家搬到了一个小农场,但她常常回到FJ的农场去拜访她的朋友。贝茜很喜欢路边的风景,不想那么快地结束她的旅途,于是她每次回农场,都会选择第二短的路径,而不象我们所习惯的那样,选择最短路。 贝茜所在的乡村有R(1<=R<=100,000)条双向道路,每条路都联结了所有的N(1<=N<=5000)个农场中的某两个。贝茜居住在农场1,她的朋友们居住在农场N(即贝茜每次旅行的目的地)。 贝茜选择的第二短的路径中,可以包含任何一条在最短路中出现的道路,并且,一条路可以重复走多次。当然咯,第二短路的长度必须严格大于最短路(可能有多条)的长度,但它的长度必须不大于所有除最短路外的路径的长度。Input
* 第1行: 两个整数,N和R,用空格隔开* 第2..R+1行: 每行包含三个用空格隔开的整数A、B和D,表示存在一条长度为 D(1 <= D <= 5000)的路连接农场A和农场B
Output
* 第1行: 输出一个整数,即从农场1到农场N的第二短路的长度Sample Input
4 41 2 100
2 4 200
2 3 250
3 4 100
Sample Output
450输出说明:
最短路:1 -> 2 -> 4 (长度为100+200=300)
第二短路:1 -> 2 -> 3 -> 4 (长度为100+250+100=450)
HINT
Source
Gold挺好的一道图论题。
第一次窝以为和洛谷 玛利亚那道题差不多,结果拿了50分,就苟且地抄了题解。
解法一:
在spfa中更新,有三种情况,注意细节(似乎较容易出错)#include<iostream> #include<cstring> #include<cstdio> #include<queue> using namespace std; const int N=5005; const int M=100005; int n,m,cnt,dis1 ,dis2 ,hd ; bool inq ; queue<int>q; struct edge { int to,nxt,val; }v[2*M]; void addedge(int x,int y,int z) { ++cnt; v[cnt].to=y; v[cnt].nxt=hd[x]; v[cnt].val=z; hd[x]=cnt; } int main() { scanf("%d%d",&n,&m); while(m--) { int x,y,z; scanf("%d%d%d",&x,&y,&z); addedge(x,y,z),addedge(y,x,z); } memset(dis1,0x3f,sizeof(dis1)); memset(dis2,0x3f,sizeof(dis2)); dis1[1]=0; inq[1]=1; q.push(1); while(!q.empty()) { int u=q.front(); q.pop(); inq[u]=0; for(int i=hd[u];i;i=v[i].nxt) { bool flg=0; if(dis1[v[i].to]>dis1[u]+v[i].val) { dis2[v[i].to]=min(dis1[v[i].to],dis2[u]+v[i].val); dis1[v[i].to]=dis1[u]+v[i].val; flg=1; } else if(dis1[v[i].to]<dis1[u]+v[i].val&&dis2[v[i].to]>dis1[u]+v[i].val) { dis2[v[i].to]=dis1[u]+v[i].val; flg=1; } else if(dis1[v[i].to]==dis1[u]+v[i].val&&dis2[v[i].to]>dis2[u]+v[i].val) { dis2[v[i].to]=dis2[u]+v[i].val; flg=1; } if(flg&&!inq[v[i].to]) { inq[v[i].to]=1; q.push(v[i].to); } } } printf("%d\n",dis2 ); return 0; }
解法二:
正反两次spfa,枚举中间的一条边(因为最多只可能有一条边与最短路不同),或一条边走了两次。#include<iostream> #include<cstring> #include<cstdio> #include<queue> using namespace std; const int N=5005; const int M=100005; const int inf=1e9+7; int n,m,ans,mn,cnt=1,hd ,dis1 ,dis2 ; bool inq ; queue<int>q; struct edge { int to,nxt,val; }v[2*M]; void addedge(int x,int y,int z) { ++cnt; v[cnt].to=y; v[cnt].nxt=hd[x]; v[cnt].val=z; hd[x]=cnt; } void spfa(int s,int *dis) { memset(dis,0x3f,N*sizeof(int)); dis[s]=0; inq[s]=1; q.push(s); while(!q.empty()) { int u=q.front(); q.pop(); inq[u]=0; for(int i=hd[u];i;i=v[i].nxt) if(dis[v[i].to]>dis[u]+v[i].val) { dis[v[i].to]=dis[u]+v[i].val; if(!inq[v[i].to]) { inq[v[i].to]=1; q.push(v[i].to); } } } } int main() { scanf("%d%d",&n,&m); while(m--) { int x,y,z; scanf("%d%d%d",&x,&y,&z); addedge(x,y,z),addedge(y,x,z); } spfa(1,dis1); spfa(n,dis2); ans=inf; mn=dis1 ; for(int i=2;i<=cnt;i++) { int u=min(dis1[v[i].to]+dis2[v[i^1].to],dis1[v[i^1].to]+dis2[v[i].to])+v[i].val; if(u!=mn&&u<ans) ans=u; } for(int i=1;i<=n;i++) for(int j=hd[i];j;j=v[j].nxt) ans=min(ans,dis1[i]+dis2[i]+2*v[j].val); printf("%d\n",ans); return 0; }
相关文章推荐
- Bzoj 1726: [Usaco2006 Nov]Roadblocks第二短路 dijkstra,堆,A*,次短路
- bzoj1726 [Usaco2006 Nov]Roadblocks第二短路
- bzoj1726 [Usaco2006 Nov]Roadblocks第二短路(spfa)
- 最短路【bzoj1726】: [Usaco2006 Nov]Roadblocks第二短路
- [Bzoj1726][Usaco2006 Nov]Roadblocks第二短路
- bzoj1726: [Usaco2006 Nov]Roadblocks第二短路
- bzoj 1726: [Usaco2006 Nov]Roadblocks第二短路
- 【次短路径/SPFA】BZOJ1726-[Usaco2006 Nov]Roadblocks第二短路
- bzoj1726【Usaco2006 Nov】Roadblocks第二短路
- BZOJ 1726: [Usaco2006 Nov]Roadblocks第二短路
- BZOJ 1726: [Usaco2006 Nov]Roadblocks第二短路( 最短路 )
- bzoj 1726: [Usaco2006 Nov]Roadblocks第二短路(A*第k短路)
- bzoj:1726: [Usaco2006 Nov]Roadblocks第二短路
- BZOJ1726: [Usaco2006 Nov]Roadblocks第二短路
- bzoj 1726: [Usaco2006 Nov]Roadblocks第二短路【dijskstra】
- 【bzoj1726】【Usaco2006 Nov】【Roadblocks第二短路】【spfa】
- 【BZOJ】1726 [Usaco2006 Nov]Roadblocks第二短路
- 1726: [Usaco2006 Nov]Roadblocks第二短路
- [Usaco2006 Nov]Roadblocks第二短路 堆优化的dijkstra
- 【bzoj1726】 Usaco2006 Nov Roadblocks第二短路 次短路模板