• 【洛谷P1491】集合位置


    题目大意:求给定的一张无向带权图的次短路。

    题解:先跑一遍 spfa 求出从起点到终点的最短路,记录路径。接着枚举删边,并重新跑 spfa,统计最小值即可。
    至于为什么 dp 做法不行,暂时还不清楚。

    代码如下

    #include <bits/stdc++.h>
    using namespace std;
    const int maxe=2e4+10;
    const int maxv=210;
    const double inf=0x3f3f3f3f;
    
    struct node{
    	int nxt,to;
    	double w;
    }e[maxe<<1];
    int tot=1,head[maxv];
    inline void add_edge(int from,int to,double w){
    	e[++tot]=node{head[from],to,w},head[from]=tot;
    }
    int n,m,pre[maxv];
    double x[maxv],y[maxv],d[maxv],ans=inf;
    bool in[maxv];
    
    inline double calc(int a,int b){
    	return sqrt((x[a]-x[b])*(x[a]-x[b])+(y[a]-y[b])*(y[a]-y[b]));
    }
    
    void read_and_parse(){
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;i++)scanf("%lf%lf",&x[i],&y[i]);
    	for(int i=1,a,b;i<=m;i++){
    		scanf("%d%d",&a,&b);
    		double c=calc(a,b);
    		add_edge(a,b,c),add_edge(b,a,c);
    	}
    }
    
    queue<int> q;
    
    void spfa(int a,int b){
    	memset(in,0,sizeof(in));
    	fill(d+1,d+n+1,inf);
    	q.push(1),in[1]=1,d[1]=0;
    	while(q.size()){
    		int u=q.front();q.pop(),in[u]=0;
    		for(int i=head[u];i;i=e[i].nxt){
    			int v=e[i].to;double w=e[i].w;
    			if((u==a&&v==b)||(v==a&&u==b))continue;
    			if(d[v]>d[u]+w){
    				d[v]=d[u]+w;
    				if(a==-1&&b==-1)pre[v]=u;
    				if(!in[v])q.push(v),in[v]=1;
    			}
    		}
    	}
    }
    
    void solve(){
    	spfa(-1,-1);
    	for(int i=n;pre[i];i=pre[i]){
    		spfa(i,pre[i]);
    		ans=min(ans,d[n]);
    	}
    	if(ans==inf)puts("-1");
    	else printf("%.2lf
    ",ans);
    }
    
    int main(){
    	read_and_parse();
    	solve();
    	return 0;
    }
    
  • 相关阅读:
    hdu--1026--Ignatius and the Princess I(bfs搜索+dfs(打印路径))
    hdu--1798--Doing Homework again(贪心)
    开启事务的两种方法
    事务的隔离级别,乐观锁,悲观锁
    树的结构,无限极关联
    微信小程序的加密解密以及小程序的支付
    微信小程序之登录连接django,以及用户的信息授权认证
    微信小程序三
    微信小程序二
    vue-cookies缓存
  • 原文地址:https://www.cnblogs.com/wzj-xhjbk/p/10085305.html
Copyright © 2020-2023  润新知