比赛 10101115 评测结果 AWWWWWWWWT
题目名称 最小密度路径 最终得分 10
用户昵称 Pom 运行时间 0.000 s
代码语言 C++ 内存使用 0.00 MiB
提交时间 2010-11-15 10:44:21
显示代码纯文本
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>

using namespace std;

const int MAXN=60;
const int MAXM=2012;
const int oo=1000000000;
const int M=MAXN*9;

struct edge
{
	int t,c;
	edge *p;
}e[MAXM],*v[MAXN];

struct fifo
{
	int num,s,dis;
}q[MAXN*10],tmp;

int map[MAXN][MAXN],i,j,k,n,m,Q,es=-1,x,y,h,t,s,sum[MAXN][MAXN];
double ans[MAXN][MAXN];
bool b[MAXN][MAXN],used[MAXN],ok[MAXN],iq[MAXN][MAXN];

inline void addedge(int i,int j,int c)
{
	e[++es].t=j; e[es].c=c; e[es].p=v[i]; v[i]=e+es;
}

void init()
{
	freopen("path.in","r",stdin);
	freopen("path.out","w",stdout);
	scanf("%d%d",&n,&m);
	memset(b,false,sizeof(b));
	memset(ok,false,sizeof(ok));
	memset(ans,0,sizeof(ans));
	for (i=1;i<=n;i++)
		for (j=1;j<=n;j++)
			ans[i][j]=map[i][j]=oo;
	for (;m>0;m--)
	{
		scanf("%d%d%d",&i,&j,&k);
		if (map[i][j]>k) map[i][j]=k;
	}
	for (i=1;i<=n;i++)
		for (j=1;j<=n;j++)
			if (map[i][j]<oo) addedge(i,j,map[i][j]);
	scanf("%d",&Q);
}

bool dfs(int u)
{
	used[u]=true;
	if (u==y) return true;
	for (edge *x=v[u];x;x=x->p)
		if (!used[x->t])
			if (dfs(x->t)) return true;
	return false;
}

void solve()
{
	scanf("%d%d",&x,&y);
	if (ok[x])
	{
		if (ans[x][y]<0) printf("OMG!\n");
		else printf("%0.3lf\n",ans[x][y]);
		return;
	}
	memset(used,false,sizeof(used));
	memset(iq,false,sizeof(iq));
	for (i=1;i<=n;i++)
		for (j=1;j<=n;j++)
			sum[i][j]=oo;
	h=t=s=1;
	q[1].num=x;
	q[1].s=0;
	q[1].dis=0;
	while (s)
	{
		tmp=q[h];
		used[tmp.num]=true;
		for (edge *E=v[tmp.num];E;E=E->p)
		{
			if (sum[E->t][tmp.s+1]>tmp.dis+E->c)
				sum[E->t][tmp.s+1]=tmp.dis+E->c;
			if (!iq[E->t][tmp.s+1])
			{
				t=(t+1)%M;
				q[t].dis=sum[E->t][tmp.s+1];
				q[t].s=tmp.s+1;
				q[t].num=E->t;
				iq[E->t][tmp.s+1]=true;
				s++;
			}
		}
		iq[tmp.num][tmp.s]=false;
		h=(h+1)%M;
		s--;
	}
	ok[x]=true;
	for (i=1;i<=n;i++)
	{
		if (!used[i])  
		{
			ans[x][i]=-10;
			continue;
		}			
		for (j=1;j<=n;j++)
			if (ans[x][i]>(double) sum[i][j]/j) ans[x][i]=(double) sum[i][j]/j;
	}
	ans[x][x]=0;
	if (ans[x][y]<0) printf("OMG!\n");
	else printf("%0.3lf\n",ans[x][y]);
}

int main()
{
	init();
	for (;Q>0;Q--)
	{
		solve();
	}
	return 0;
}