2407: 探险
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 170 Solved: 95
[Submit][Status][Discuss]
Description
探险家小T好高兴!X国要举办一次溶洞探险比赛,获奖者将得到丰厚奖品哦!小T虽然对奖品不感兴趣,但是这个大振名声的机会当然不能错过!
比赛即将开始,工作人员说明了这次比赛的规则:每个溶洞和其他某些溶洞有暗道相连。两个溶洞之间可能有多条道路,也有可能没有,但没有一条暗道直接从自己连到自己。参赛者需要统一从一个大溶洞出发,并再次回到这个大溶洞。
如果就这么点限制,那么问题就太简单了,可是举办方又提出了一个条件:不能经过同一条暗道两次。这个条件让大家犯难了。这该怎么办呢?
到了大溶洞口后,小T愉悦地发现这个地方他曾经来过,他还记得有哪些暗道,以及通过每条暗道的时间。小T现在向你求助,你能帮他算出至少要多少时间才能回到大溶洞吗?
Input
第一行两个数n,m表示溶洞的数量以及暗道的数量。
接下来m行,每行4个数s、t、w、v,表示一个暗道连接的两个溶洞s、t,这条暗道正着走(s à t)的所需要的时间w,倒着走(t à s)所需要的时间v。由于溶洞的相对位置不同,w与v可能不同。
Output
输出一行一个数t,表示最少所需要的时间。
Sample Input
3 3
1 2 2 1
2 3 4 5
3 1 3 2
1 2 2 1
2 3 4 5
3 1 3 2
Sample Output
8
HINT
N<=10000,M<=200000,1<=W,V<=10000
双倍经验啊(福慧双修数据范围大一点)
这两道题都是rank1 还比rank2快好多 哈哈哈哈
#include<cmath>
#include<ctime>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<iomanip>
#include<vector>
#include<string>
#include<bitset>
#include<queue>
#include<set>
#include<map>
using namespace std;
typedef long long ll;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return x*f;
}
void print(ll x)
{if(x<0)x=-x,putchar('-');if(x>=10)print(x/10);putchar(x%10+'0');}
const int N=10100,M=400100,inf=0X3f3f3f3f;
int n,m,T;
int ecnt,last[N];
struct EDGE{int to,nt,val;}e[M];
inline void add(int u,int v,int val)
{e[++ecnt]=(EDGE){v,last[u],val};last[u]=ecnt;}
int U[M],V[M],VAL[M],tot;
inline void insert(int u,int v,int val)
{U[++tot]=u;V[tot]=v;VAL[tot]=val;}
struct node{int pos,dis;friend bool operator <(const node &x,const node &y){return x.dis>y.dis;}};
bool vis[N];
int dis[N],p[N];
priority_queue<node>q;
void dijkstra()
{
memset(vis,0,sizeof(vis));
memset(dis,0X3f,sizeof(dis));
q.push((node){1,0});dis[1]=0;
register int u,i;
while(!q.empty())
{
u=q.top().pos;q.pop();
if(vis[u])continue;vis[u]=1;
for(i=last[u];i;i=e[i].nt)if(dis[e[i].to]>dis[u]+e[i].val)
{
dis[e[i].to]=dis[u]+e[i].val;
u==1?p[e[i].to]=e[i].to:p[e[i].to]=p[u];
if(!vis[e[i].to])q.push((node){e[i].to,dis[e[i].to]});
}
}
}
void rebuild()
{
register int u,i;
for(u=1;u<=n;++u)
for(i=last[u];i;i=e[i].nt)
{
if(e[i].to==1) {p[u]^u?insert(1,T,dis[u]+e[i].val):insert(u,T,e[i].val);continue;}
if(u==1) {if(p[e[i].to]^e[i].to)insert(1,e[i].to,e[i].val);continue;}
p[u]^p[e[i].to]?insert(1,e[i].to,dis[u]+e[i].val):insert(u,e[i].to,e[i].val);
}
ecnt=0;memset(last,0,sizeof(last));
for(i=1;i<=tot;++i)add(U[i],V[i],VAL[i]);
}
int main()
{
n=read();m=read();T=n+1;
register int i,u,v,val1,val2;
for(i=1;i<=m;++i)
{
u=read();v=read();val1=read();val2=read();
add(u,v,val1);add(v,u,val2);
}
dijkstra();rebuild();dijkstra();
if(dis[T]==inf){puts("-1");return 0;}
print(dis[T]);puts("");
return 0;
}
/*
3 3
1 2 2 1
2 3 4 5
3 1 3 2
8
*/