SSL 1864 JZOJ 1368 燃烧木棍#floyd#

SSL比赛


题目

计算从哪里开始点火,使得燃烧的总时间最短,输出最短时间。
这里写图片描述


分析

把木棍分成两小段
floyd求出被燃烧的最短时间
再求出答案


floyd代码

#include <cstdio>
#include <climits>
#include <cctype>
#define eij e[i][j]!=INT_MAX
#define dxi d[x][i]!=INT_MAX
using namespace std;
struct node{int x1,y1,x2,y2,t;}f[41];
struct nobe{int xx,yy;}v[83];
int n,m,e[83][83],d[83][83]; double ans=INT_MAX,cc;
int in(){
	int ans=0,f=1; char c=getchar();
	while (!isdigit(c)&&c!='-') c=getchar();
	if (c=='-') c=getchar(),f=-f;
	while (isdigit(c)) ans=ans*10+c-48,c=getchar();
	return ans*f;
}
double min(double a,double b){return (a<b)?a:b;}
double max(double a,double b){return (a>b)?a:b;}
int gett(int x,int y){
	for (int i=1;i<=m;i++) if (v[i].xx==x&&v[i].yy==y) return i;//找到返回
    v[++m].xx=x; v[m].yy=y;
    for (int i=1;i<m;i++) e[i][m]=e[m][i]=INT_MAX;//初始化
    e[m][m]=0; return m;
}
void add(int x1,int y1,int x2,int y2,int t){
	int i=gett(x1,y1),j=gett(x2,y2);
	e[i][j]=e[j][i]=t;
} 
double anw(int x){
	double kk=0,ss;
	for (int i=1;i<=m;i++) 
	if (dxi) kk=max(kk,d[x][i]);
	for (int i=1;i<m;i++)
	for (int j=i+1;j<=m;j++)
	if (eij&&d[x][i]<d[x][j]+e[i][j]&&d[x][j]<d[x][i]+d[i][j]){//是否相连
		if (d[x][i]<d[x][j]) ss=d[x][j]+(e[i][j]-(d[x][j]-d[x][i]))/2.0;//计算出烧完的时间
		else ss=d[x][i]+(e[i][j]-(d[x][i]-d[x][j]))/2.0;//计算出烧完的时间
		kk=max(kk,ss);//求最大值
	}
	return kk;
}
void init();
int main(){
	freopen("fire.in","r",stdin);
	freopen("fire.out","w",stdout);
	init();//初始化
	for (int k=1;k<=m;k++)
    for (int i=1;i<=m;i++)
    for (int j=1;j<=m;j++)
    if (d[i][j]>(long long)d[i][k]+d[k][j])
    d[i][j]=d[i][k]+d[k][j];//floyd
    for (int i=1;i<=m;i++)
    if (!(v[i].xx%2)&&!(v[i].yy%2)) //在两头cc=anw(i),ans=min(ans,cc);
    printf("%.4lf",ans/2.0); return 0;
} 
void init(){
	n=in(); for (int i=1;i<=n;i++) 
	f[i].x1=in(),f[i].y1=in(),f[i].x2=in(),f[i].y2=in(),f[i].t=in();
    for (int i=1;i<=n;i++) add(f[i].x1*2,f[i].y1*2,f[i].x1+f[i].x2,f[i].y1+f[i].y2,f[i].t),add(f[i].x1+f[i].x2,f[i].y1+f[i].y2,f[i].x2*2,f[i].y2*2,f[i].t);//截成两小段
    for (int i=0;i<=m+1;i++) for (int j=0;j<=m+1;j++) d[i][j]=e[i][j];
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值