当前位置: 代码迷 >> 综合 >> NOI2014 魔法森林
  详细解决方案

NOI2014 魔法森林

热度:57   发布时间:2023-12-16 00:37:59.0

这道题…正解是LCT(然而我不会),所以把我的动点SPFA发上来混一波23333,对于这个问题,应该是类似瓶颈生成树??对此,我们可以很好想出一个贪心+最短路策略,我们先把每一条边按照A的权值排序,然后枚举每一条边,跑一遍对于B的最短路,之后用新加入的边的A权值更新一下到终点的答案,然后….然后就完事了!一道考数据结构的题就这样水过23333 SPFA时间复杂度蜜汁不科学啊啊啊啊啊 代码如下

#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
int n,m,top=0,maxa=0,ans=1e9;
int dis[100005],f[100005];
bool inq[100005];
struct edge{int x,y,a,b;
}p[200005];
inline bool cmp(edge x,edge y){if(x.a==y.a) return x.b<y.b;return x.a<y.a;
}
struct ddf{int nex,to,b;
}a[200005];
inline void add(int x,int y,int b){a[++top]=(ddf){f[x],y,b};f[x]=top;
}
int main(){scanf("%d%d",&n,&m);for(int i=1;i<=m;i++)scanf("%d%d%d%d",&p[i].x,&p[i].y,&p[i].a,&p[i].b);sort(p+1,p+m+1,cmp);for(int i=2;i<=n;i++) dis[i]=1e9;for(int i=1;i<=m;i++){add(p[i].x,p[i].y,p[i].b);add(p[i].y,p[i].x,p[i].b);queue<int> q1;q1.push(p[i].x),q1.push(p[i].y);inq[p[i].x]=1,inq[p[i].y]=1;while(!q1.empty()){int u=q1.front();            for(int i=f[u];i;i=a[i].nex){int v=a[i].to;if(max(a[i].b,dis[u])<dis[v]){dis[v]=max(a[i].b,dis[u]);if(!inq[v]) inq[v]=1,q1.push(v);}}q1.pop();inq[u]=0;}if(p[i].a+dis[n]<ans) ans=p[i].a+dis[n];}if(ans==1e9) printf("-1");else printf("%d",ans);return 0;
}