【P2387】魔法森林(SPFA非正解)

  题目链接

  不会LCTqwq,看题解似乎SPFA也可以。

  把边按a排序,从小到大每加一条边就以b为距离跑一遍SPFA,类似于Kruskal的想法吧……

  貌似是个暴力

  (luoguLCT模块的题我都快通过了,然而还是不会LCT蛤蛤蛤)

  

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<cctype>
#include<queue>
#define maxn 50050
#define maxm 500500
using namespace std;
inline long long read(){
long long num=,f=;
char ch=getchar();
while(!isdigit(ch)){
if(ch=='-') f=-;
ch=getchar();
}
while(isdigit(ch)){
num=num*+ch-'';
ch=getchar();
}
return num*f;
} struct Edge{
int from,next,to,vala,valb;
bool operator <(const Edge a)const{
return vala<a.vala;
}
}edge[maxm],d[maxm];
int head[maxn],num;
inline void add(int from,int to,int vala,int valb){
edge[++num]=(Edge){from,head[from],to,vala,valb};
head[from]=num;
} bool vis[maxn];
int dis[maxn];
int n,m;
int spfa(int sta,int stb){
queue<int>q; q.push(); q.push(sta); q.push(stb);
memset(vis,,sizeof(vis)); vis[]=vis[sta]=vis[stb]=;
while(!q.empty()){
int from=q.front();q.pop(); vis[from]=;
for(int i=head[from];i;i=edge[i].next){
int to=edge[i].to;
if(dis[to]<=max(dis[from],edge[i].valb)) continue;
dis[to]=max(dis[from],edge[i].valb);
if(vis[to]) continue;
vis[to]=; q.push(to);
}
}
return dis[n];
} int main(){
freopen("testdata.in.txt","r",stdin);
n=read(),m=read();
for(int i=;i<=m;++i) d[i]=(Edge){read(),,read(),read(),read()};
sort(d+,d+m+);
memset(dis,/,sizeof(dis)); dis[]=;
int ans=0x7fffffff;
for(int i=;i<=m;++i){
add(d[i].from,d[i].to,d[i].vala,d[i].valb);
add(d[i].to,d[i].from,d[i].vala,d[i].valb);
int now=d[i].vala+spfa(d[i].from,d[i].to);
if(now<ans) ans=now;
}
printf("%d\n",ans==?-:ans);
return ;
}
上一篇:mysql 两主一从环境搭建(5.7.24)


下一篇:Bzoj 1537: [POI2005]Aut- The Bus 题解 [由暴力到正解]