题目描述:https://www.luogu.org/problemnew/show/U38181
读完题之后,我门发现这是一道裸的最短路,写个我们大家都喜欢的SPFA就可以秒过
考场上的思维自以为没有什么问题,随手写完就交了
考完一看发现挂了,一个点都没过,就有点蒙,然后发现是Re
下面的这行代码大家一定要记住(以后都这么写)
long long main()
这个悲惨的故事大家一定要铭记在心,然而你以为这就是事情的全部吗?
不不不,我国服被卡王今天就要卡死在这里
我们会发现,这道题目在最后有一个分类讨论,就是有可能Harry一个人去两个房间会更快(主角光环就是nb)
因为是无向图,所以天真的我认为只用判断一次,然而我还是太年轻,Harry先去不同的房间好肥的时间可能不同(出题人太巨了)
然后除了这些也就没有什么思维难度了,基本上是个模板题
下面给出代码:
#include<iostream> #include<cmath> #include<cstdio> #include<cstdlib> #include<cstring> #include<string> #include<algorithm> #include<queue> using namespace std; inline long long min(long long a,long long b){return a<b?a:b;} inline long long max(long long a,long long b){return a>b?a:b;} inline long long rd() { long long x=0,f=1; char c=getchar(); for(;!isdigit(c);c=getchar()) if(c=='-') f=-1; for(;isdigit(c);c=getchar()) x=x*10+c-'0'; return x*f; } inline void write(long long x) { if(x<0) putchar('-'),x=-x; if(x>9) write(x/10); putchar(x%10+'0'); } long long n,m,k; long long head[100006],to[1000006],v[1000006],nxt[1000006]; long long total=0; long long dis[100006]; long long dis2[100006]; long long book[100006]; void add(long long x,long long y,long long z){ total++; to[total]=y; v[total]=z; nxt[total]=head[x]; head[x]=total; return ; } deque <long long> q; long long vis[100006]; void spfa_r(long long x){//SPFA板子 if(book[x]) return ; memset(dis,127,sizeof(dis)); memset(vis,0,sizeof(vis)); q.push_back(x); vis[x]=1; dis[x]=0; while(!q.empty()){ long long h=q.front(); q.pop_front(); vis[h]=0; for(long long e=head[h];e;e=nxt[e]){ if(book[to[e]]) continue; if(dis[to[e]]>dis[h]+v[e]){ dis[to[e]]=dis[h]+v[e]; if(!vis[to[e]]){ if(!q.empty()&&dis[to[e]]<=dis[q.front()]) q.push_front(to[e]); else q.push_back(to[e]); vis[to[e]]=1; } } } } return ; } void spfa_h(long long x){ memset(dis2,127,sizeof(dis2)); memset(vis,0,sizeof(vis)); q.push_back(x); vis[x]=1; dis2[x]=0; while(!q.empty()){ long long h=q.front(); q.pop_front(); vis[h]=0; for(long long e=head[h];e;e=nxt[e]){ if(dis2[to[e]]>dis2[h]+v[e]){ dis2[to[e]]=dis2[h]+v[e]; if(!vis[to[e]]){ if(!q.empty()&&dis2[to[e]]<=dis2[q.front()]) q.push_front(to[e]); else q.push_back(to[e]); vis[to[e]]=1; } } } } return ; } int main() { n=rd(),m=rd(),k=rd(); for(long long i=1;i<=k;i++){ long long x=rd(); book[x]=1; } for(long long i=1;i<=m;i++){ long long x=rd(),y=rd(),z=rd(); add(x,y,z); add(y,x,z); } long long l=rd(),r=rd(); spfa_r(1);//因为有的房间只有Harry能去 spfa_h(1);//所以要分开写(滑稽) long long ans=min(max(dis2[l],dis[r]),max(dis2[r],dis[l]));//两个人去的房间取最优(在这里卡了半天) long long set=dis2[l]; long long sett=dis2[r]; spfa_h(l);//Harry先从l点开始 ans=min(ans,set+dis2[r]); spfa_h(r);//刚才把这行写在了上面 ans=min(ans,sett+dis2[l]); printf("%lld",ans); return 0; }