zoukankan      html  css  js  c++  java
  • [NOI2014]魔法森林[最短路 spfa]

    [NOI2014]魔法森林

    一条边有(a_i,b_i)两个权值 求(1->n)路径上(a)的最大值与(b)的最大值之和的最小

    ==有lct的做法 但是spfa动态加点的做法也很巧妙!

    先将其按(a)从小到大排序 然后依次加入边

    对于ans的每次更新 当ans第一次更新时说明在加入这条边后才存在(1->n)的路 而新加的这条边一定在(1->n)的路径上
    之后的更新也差不多同理(寄几想一想为什么

    每加入一条边 就只用从新加入的这条边的(u,v)来开始更新 不用跑完==

    int dis[N],vis[N];
    queue<int> q;
    void spfa(int a,int b){
    	vis[a]=vis[b]=1;
    	q.push(a),q.push(b);
    	while(!q.empty()){
    		int u=q.front();q.pop(),vis[u]=0;
    		for(int i=head[u],v,w;i;i=e[i].nxt)
    			if(dis[v=e[i].v]>Max(dis[u],w=e[i].w)){
    				dis[v]=Max(dis[u],e[i].w);
    				if(!vis[v]) q.push(v),vis[v]=1;
    			}
    	}
    }
    
    int main(){
    #ifndef ONLINE_JUDGE
       // freopen("in.txt","r",stdin);
    #endif
    	rd(n),rd(m);ans=inf;
    	memset(dis,inf,sizeof(dis));
    	for(int i=1,u,v,a,b;i<=m;++i) rd(u),rd(v),rd(a),rd(b),E[i]=(node){u,v,a,b};
    	sort(E+1,E+m+1,cmp);
    	dis[1]=0;
    	for(int i=1,u,v,w;i<=m;++i){
    		u=E[i].u,v=E[i].v,w=E[i].b;
    		add(u,v,w),add(v,u,w);
    		spfa(u,v);
    		ans=Min(ans,dis[n]+E[i].a);
    	}
    	if(ans==inf) return puts("-1"),0;
    	printf("%d",ans);
    	return 0;
    }
    
  • 相关阅读:
    DHCP协议详解(硬件方面原理)
    ASP.NET安全认证
    JAVA打包成.jar可运行项目
    JAVA菜单事件
    JAVA事件概述
    JAVA对话框事件
    各种事件汇聚
    把原来可空的列变成主键
    搜索模式中的所有表
    JAVA选项事件
  • 原文地址:https://www.cnblogs.com/lxyyyy/p/11668255.html
Copyright © 2011-2022 走看看