记录编号 96763 评测结果 AAAAAAAAAA
题目名称 [SGU U236]贪心路径 最终得分 100
用户昵称 Gravatarcstdio 是否通过 通过
代码语言 C++ 运行时间 0.013 s
提交时间 2014-04-14 21:30:57 内存使用 0.40 MiB
显示代码纯文本
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
const int SIZEN=60;
const double eps=1e-10,INF=1e10;
double C[SIZEN][SIZEN]={0},T[SIZEN][SIZEN]={0};
bool cn[SIZEN][SIZEN]={0};//是否有边
double len[SIZEN][SIZEN]={0};
double dist[SIZEN]={0};
int pre[SIZEN]={0};
int N,M;
int SPFA(int S,double mid,int pre[SIZEN],double f[SIZEN]){
	bool inq[SIZEN]={0};
	queue<int> Q;
	int tim[SIZEN]={0};
	memset(pre,0,sizeof(pre));
	for(int i=1;i<=N;i++) f[i]=INF;
	for(int i=1;i<=N;i++) for(int j=1;j<=N;j++) if(cn[i][j]) len[i][j]=mid*T[i][j]-C[i][j];
	f[S]=0;Q.push(S);inq[S]=true;
	while(!Q.empty()){
		int x=Q.front();Q.pop();inq[x]=false;
		if(tim[x]>N) return x;
		for(int i=1;i<=N;i++){
			if(!cn[x][i]) continue;
			if(f[i]>f[x]+len[x][i]){
				f[i]=f[x]+len[x][i];
				pre[i]=x;
				if(!inq[i]){
					inq[i]=true;
					Q.push(i);
					tim[i]++;
				}
			}
		}
	}
	return 0;
}
double find(double left,double right){
	if(right-left<=eps) return left;
	double mid=(left+right)/2;
	if(SPFA(1,mid,pre,dist)) return find(mid,right);
	else return find(left,mid);
}
void work(void){
	double ans=find(0,100.0);
	int x=SPFA(1,ans,pre,dist);
	if(!x){//没有负"一点"的负权边
		printf("0\n");
		return;
	}
	printf("%.2lf\n",ans);
	return;
	//下面是输出方案的内容
	int deg[SIZEN]={0};
	int tot=0;
	int path[SIZEN]={0};
	while(deg[x]<=1){
		deg[x]++;
		if(deg[x]==2) path[++tot]=x;
		x=pre[x];
	}
	printf("%d\n",tot);
	for(int i=tot;i>=1;i--) printf("%d ",path[i]);
	printf("\n");
}
void read(void){
	memset(cn,0,sizeof(cn));
	scanf("%d%d",&N,&M);
	int a,b;
	for(int i=1;i<=M;i++){
		scanf("%d%d",&a,&b);
		scanf("%lf%lf",&C[a][b],&T[a][b]);
		cn[a][b]=true;
	}
}
int main(){
	freopen("greedypath.in","r",stdin);
	freopen("greedypath.out","w",stdout);
	read();
	work();
	return 0;
}