【BZOJ2407】探险

Description

探险家小T好高兴!X国要举办一次溶洞探险比赛,获奖者将得到丰厚奖品哦!小T虽然对奖品不感兴趣,但是这个大振名声的机会当然不能错过!
比赛即将开始,工作人员说明了这次比赛的规则:每个溶洞和其他某些溶洞有暗道相连。两个溶洞之间可能有多条道路,也有可能没有,但没有一条暗道直接从自己连到自己。参赛者需要统一从一个大溶洞出发,并再次回到这个大溶洞。
如果就这么点限制,那么问题就太简单了,可是举办方又提出了一个条件:不能经过同一条暗道两次。这个条件让大家犯难了。这该怎么办呢?
到了大溶洞口后,小T愉悦地发现这个地方他曾经来过,他还记得有哪些暗道,以及通过每条暗道的时间。小T现在向你求助,你能帮他算出至少要多少时间才能回到大溶洞吗?

Input

第一行两个数n,m表示溶洞的数量以及暗道的数量。

接下来m行,每行4个数s、t、w、v,表示一个暗道连接的两个溶洞s、t,这条暗道正着走(à t)的所需要的时间w,倒着走(à s)所需要的时间v。由于溶洞的相对位置不同,wv可能不同。

Output

输出一行一个数t,表示最少所需要的时间。

Sample Input

3 3
1 2 2 1
2 3 4 5
3 1 3 2

Sample Output

8

HINT

N<=10000,M<=200000,1<=W,V<=10000

题解:如果想不经过重复的边回到1号点,那么只需要满足从1出发时走的点不同于回到1时走的点即可。那么我们先跑一边spfa,在求最短路的同时维护一个pre数组,代表如果沿最短路走到i,则从i出发时走的第一个点是pre[i]。那么我们所求的路径一定是从一些pre=x的点走到一些pre!=x的点再走到1号点。那么我们可以采用如下方法构造新图。

新建汇点n+1,对于边(u,v,len),如果pre[u]!=pre[v],则直接连从1到v,边权为dis[u]+len的边;否则连从u到v,边权len的边。
特别地,如果u=1,那么若pre[v]!=v,连从1到v边权dis[v]的边;否则不连。
如果v=1,那么若pre[u]!=u,直接用dis[u]+len更新答案;否则连u到n+1,边权len的边。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <utility>
#define mp(A,B) make_pair(A,B)
using namespace std;
const int maxn=10010;
const int maxm=400010;
int n,m,cnt,ans;
queue<int> q;
int pre[maxn],inq[maxn],dis[maxn],pa[maxm],pb[maxm],pc[maxm];
int to[maxm],next[maxm],val[maxm],head[maxn];
void add(int a,int b,int c)
{
to[cnt]=b,val[cnt]=c,next[cnt]=head[a],head[a]=cnt++;
}
void spfa()
{
int u,i;
while(!q.empty())
{
u=q.front(),q.pop(),inq[u]=0;
for(i=head[u];i!=-1;i=next[i]) if(dis[to[i]]>dis[u]+val[i])
{
dis[to[i]]=dis[u]+val[i],pre[to[i]]=pre[u];
if(!inq[to[i]]) inq[to[i]]=1,q.push(to[i]);
}
}
}
inline int rd()
{
int ret=0,f=1; char gc=getchar();
while(gc<'0'||gc>'9') {if(gc=='-')f=-f; gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar();
return ret*f;
}
int main()
{
n=rd(),m=rd();
int i,a,b,c,d;
memset(head,-1,sizeof(head));
for(i=1;i<=m;i++)
a=rd(),b=rd(),c=rd(),d=rd(),add(a,b,c),pa[cnt]=a,pb[cnt]=b,pc[cnt]=c,add(b,a,d),pa[cnt]=b,pb[cnt]=a,pc[cnt]=d;
memset(dis,0x3f,sizeof(dis));
dis[1]=0;
for(i=head[1];i!=-1;i=next[i]) dis[to[i]]=val[i],q.push(to[i]),inq[to[i]]=1,pre[to[i]]=to[i];
spfa();
memset(head,-1,sizeof(head)),cnt=0;
ans=1<<30;
for(i=1;i<=2*m;i++)
{
if(pa[i]==1)
{
if(pre[pb[i]]!=pb[i]) add(1,pb[i],pc[i]);
}
else if(pb[i]==1)
{
if(pre[pa[i]]==pa[i]) add(pa[i],n+1,pc[i]);
else ans=min(ans,dis[pa[i]]+pc[i]);
}
else
{
if(pre[pa[i]]==pre[pb[i]]) add(pa[i],pb[i],pc[i]);
else add(1,pb[i],dis[pa[i]]+pc[i]);
}
}
memset(dis,0x3f,sizeof(dis));
dis[1]=0,q.push(1);
spfa(),ans=min(ans,dis[n+1]);
if(ans==1<<30||ans==0x3f3f3f3f) printf("-1");
else printf("%d",ans);
return 0;
}

【BZOJ2407/4398】探险/福慧双修 最短路建模的更多相关文章

  1. BZOJ2407/4398:探险/福慧双修(最短路)

    Description 探险家小T好高兴!X国要举办一次溶洞探险比赛,获奖者将得到丰厚奖品哦!小T虽然对奖品不感兴趣,但是这个大振名声的机会当然不能错过! 比赛即将开始,工作人员说明了这次比赛的规则: ...

  2. POJ 1062 昂贵的聘礼 【带限制的最短路/建模】

    年轻的探险家来到了一个印第安部落里.在那里他和酋长的女儿相爱了,于是便向酋长去求亲.酋长要他用10000个金币作为聘礼才答应把女儿嫁给他.探险家拿不出这么多金币,便请求酋长降低要求.酋长说:" ...

  3. [USACO14OPEN] Dueling GPS's[最短路建模]

    题目描述 Farmer John has recently purchased a new car online, but in his haste he accidentally clicked t ...

  4. bzoj 2118 墨墨的等式 - 图论最短路建模

    墨墨突然对等式很感兴趣,他正在研究a1x1+a2y2+…+anxn=B存在非负整数解的条件,他要求你编写一个程序,给定N.{an}.以及B的取值范围,求出有多少B可以使等式存在非负整数解. Input ...

  5. Vijos1404遭遇战[最短路建模]

    背景 你知道吗,SQ Class的人都很喜欢打CS.(不知道CS是什么的人不用参加这次比赛). 描述 今天,他们在打一张叫DUSTII的地图,万恶的恐怖分子要炸掉藏在A区的SQC论坛服务器!我们SQC ...

  6. POJ1062昂贵的聘礼[最短路建模]

    昂贵的聘礼 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 45892   Accepted: 13614 Descripti ...

  7. BZOJ2118墨墨的等式[数论 最短路建模]

    2118: 墨墨的等式 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 1317  Solved: 504[Submit][Status][Discus ...

  8. BZOJ4289 Tax 最短路建模

    给定一个带边权的无向图,求1到n的最小代价路径.经过一个点的代价是路径上这个点的入边和出边的较大权值. \(n \le 100000, m \le 200000\). 一般的建图是考虑每个点,其入边和 ...

  9. hdu 6071 Lazy Running 最短路建模

    Lazy Running Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others) P ...

随机推荐

  1. Hibernate分页功能数据重复问题

    今天遇到一个很憋屈的问题那就是hibernate分页查询中出现重复数据,本来一直没有在意,以为是数据问题,但是一查程序和数据都没有问题,继续深入查看,找到问题了就是order By 时出的问题,唉.. ...

  2. C# this.Invoke()的作用与用法

    Invoke()的作用是:在应用程序的主线程上执行指定的委托.一般应用:在辅助线程中修改UI线程( 主线程 )中对象的属性时,调用this.Invoke();   在多线程编程中,我们经常要在工作线程 ...

  3. 关于http和https淘宝支付宝跨域解决方法研究

    关于http和http跨域淘宝解决方式研究: http://buyer.trade.taobao.com/trade/pay.htm?spm=a1z01.2.3.4.0.wZAGp9&bizO ...

  4. 解决Mac安装M2Crypto提示无法找到openssl头文件问题

    大概是这种问题 running build running build_py running build_ext building'M2Crypto.__m2crypto' extension swi ...

  5. Spark-Join优化之Broadcast

    适用场景 进行join中至少有一个RDD的数据量比较少(比如几百M,或者1-2G) 因为,每个Executor的内存中,都会驻留一份广播变量的全量数据 Broadcast与map进行join代码示例 ...

  6. elasticsearch 基础性操作

    1 基础概念 Elasticsearch是一个近实时的系统,从你写入数据到数据可以被检索到,一般会有1秒钟的延时.Elasticsearch是基于Lucene的,Lucene的读写是两个分开的句柄,往 ...

  7. Android学习(十二) ContentProvider

    一.ContentProvider简介       当应用继承ContentProvider类,并重写该类用于提供数据和存储数据的方法,就可以向其他应用共享其数据.虽然使用其他方法也可以对外共享数据, ...

  8. django book学习问题记录

    —————————————————————————————————— 位置:第五章<模型> 问题描述(已解决): >>> p1 = Publisher.objects.c ...

  9. cocos2d-x 3.0 场景切换特效汇总

    cocos2d-x 3.0中场景切换特效比較多,并且游戏开发中也常常须要用到这些特效.来使场景切换时不至于那么干巴,遂这里汇总一下,开发中使用. 场景切换用到导演类Directory,大多数用的都是替 ...

  10. 基于RxJava2+Retrofit2精心打造的Android基础框架

    代码地址如下:http://www.demodashi.com/demo/12132.html XSnow 基于RxJava2+Retrofit2精心打造的Android基础框架,包含网络.上传.下载 ...