BZOJ 2407: 探险/BZOJ 4398: 福慧双修 dijkstra 构造

来源:互联网 发布:内网穿透软件 linux 编辑:程序博客网 时间:2024/05/16 06:49

2407: 探险

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 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。由于溶洞的相对位置不同,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


双倍经验啊(福慧双修数据范围大一点)

这两道题都是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 31 2 2 12 3 4 53 1 3 28*/