[HAOI2009] 旅行

  套用Dijstra算法求解。

  因为概率是越乘越小,而我们要求最大的。

  而路程是越加越长,我们要求最短的。

  所以可以套用最短路贪心算法。

  但是求最长路就不能用套最短路算法,而要边权取负,同加一个数为正这种方法。

// q.c

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
using namespace std;
const int M=10000;
int n,m,cnt,head[M+10];
double dis[M+10];
bool done[M+10];
struct Edge {
	int u,v,next; double w;
	Edge():u(0),v(0),next(-1),w(0) {}
}ed[M*3<<1];
struct Node {
	int u; double w;
	bool operator < (const Node &A) const {
		return w<A.w;
	}
};
void add_edge(int a,int b,double c) {
	ed[++cnt].u=a,ed[cnt].v=b,ed[cnt].w=c,ed[cnt].next=head[a],head[a]=cnt;
	ed[++cnt].u=b,ed[cnt].v=a,ed[cnt].w=c,ed[cnt].next=head[b],head[b]=cnt;
}
void dijstra(int s) {
	priority_queue<Node> q;
	dis[s]=1.0;
	q.push((Node){s,dis[s]});
	while(!q.empty()) {
		Node p=q.top(); q.pop();
		if(done[p.u]) continue;
		done[p.u]=true;
		for(int i=head[p.u];i!=-1;i=ed[i].next) {
			Edge e=ed[i];
			if(dis[e.v]<dis[e.u]*e.w) {
				dis[e.v]=dis[e.u]*e.w;
				q.push((Node){e.v,dis[e.v]});
			}
		}
	}
}
int main() {
	freopen("toura.in","r",stdin);
	freopen("toura.out","w",stdout);
	memset(head,-1,sizeof(head));
	scanf("%d%d",&n,&m);
	int a,b,c;
	while(m--) {
		scanf("%d%d%d",&a,&b,&c);
		add_edge(a,b,c/100.0);
	}
	dijstra(1);
	printf("%.6lf\n",dis[n]*100);
	return 0;
}

 

posted @ 2018-04-12 09:01  qjs12  阅读(93)  评论(0编辑  收藏  举报