次短路

RT,当不能重复经过点时,删除最短路上的每一条边,然后再分别跑最短路。

#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
using namespace std;
struct edge {
	int nxt,to;
	double val;
} e[40005];
int tot,head[205];
void add(int u,int v,double w) {
	e[++tot].to=v;
	e[tot].val=w;
	e[tot].nxt=head[u];
	head[u]=tot;
}
int n,m,s1,s2,x[205],y[205];
double ans=0x3f3f3f3f;
int f[205];
double d[205];
bool vis[205];
bool flag=false;
struct ed {
	int u;
	double w;
	friend bool operator <(const ed a1,const ed b1) {
		return a1.w>b1.w;
	}
};
priority_queue<ed>q;
void dijkstra(int s) {
	for(int i=1; i<=n; i++)d[i]=0x3f3f3f3f;
	memset(vis,0,sizeof(vis));
	d[s]=0;
	q.push((ed) {
		s,0
	});
	while(!q.empty()) {
		int u=q.top().u;
		q.pop();
		for(int i=head[u]; i; i=e[i].nxt) {
			int v=e[i].to;
			double w=e[i].val;
			if(u==s1&&v==s2)continue;
			if(d[u]+w<d[v]) {
				d[v]=d[u]+w;
				if(flag==false)f[v]=u;
				if(!vis[v]) {
					vis[v]=true;
					q.push((ed) {
						v,d[v]
					});
				}
			}
		}
	}
}
int dis(int x1,int y1,int x2,int y2) {
	return (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);
}
int main() {
	freopen("marsh.in","r",stdin);
	freopen("marsh.out","w",stdout);
	cin>>n>>m;
	for(int i=1; i<=n; i++)cin>>x[i]>>y[i];
	for(int i=1; i<=m; i++) {
		int u,v;
		cin>>u>>v;
		if(u==v)continue;
		add(u,v,sqrt(dis(x[u],y[u],x[v],y[v])));
		add(v,u,sqrt(dis(x[u],y[u],x[v],y[v])));
	}
	dijkstra(1);
	flag=true;
	int t=n;
	while(t!=1) {
		s1=f[t],s2=t;
		dijkstra(1);
		ans=min(ans,d[n]);
		t=f[t];
	}
	printf("%.2lf",ans);
	return 0;
}
上一篇:【高精度】大整数加法


下一篇:vmware workstation 网络管理