zoukankan      html  css  js  c++  java
  • 【洛谷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;
    }
    
  • 相关阅读:
    JavaScript入门二
    JavaScript入门
    CSS样式之补充
    CSS样式之操作属性二
    隔空手势操作
    项目管理培训(2)
    uoot启动过程
    new work
    库函数开发步骤 (转)
    keil(持续更新)
  • 原文地址:https://www.cnblogs.com/wzj-xhjbk/p/10085305.html
Copyright © 2011-2022 走看看