PC的机器设备 dijkstra最短路径

I. PC的机器设备

描述

HenuACM团队的PC同学设计出一种节能的机器设备。它的内部结构是由 N 个齿轮组成。整个机器设备有 一个驱动齿轮,当启动它时,它立即按 10,000 圈/小时转速顺时针转动,然后它又带动与它相切 的齿轮反方向,即逆时针转动。齿轮之间互相作用,每个齿轮都可能驱动着多个齿轮,最终带动 一个工作齿轮完成相应的任务。 在这套设备中,记录了每个齿轮的圆心坐标和齿轮半径。已知驱动齿轮位于(0,0),最终的 工作齿轮位于(Xt, Yt)。 但是WHR想知道传动序列中所有齿轮的转速。所谓传动序列,即能量由驱动齿轮传送,最 后到达工作齿轮的过程中用到的所有齿轮。能量传送过程是,在一个半径为 R,转速为 S 圈/每小 时的齿轮的带动下,与它相切的半径为 R’的齿轮的转速为-S*R/R‘ 转/小时。负号的意思是, 表 示按反方向转动。 

1546184470718.png

已知,机器设备中除了驱动齿轮以外,所有齿轮都可能被另外某个齿轮带动,并且不会出现 2 个不同的齿轮带动同一个齿轮的情况。 你的任务是计算整个传动序列中所有齿轮的能量之和。即所有齿轮转速的绝对值之和。

Input

第一行: T 表示以下有 T 组测试数据(1≤T ≤8)

对每组测试数据: 第 1 行:N Xt Yt (2≤N ≤1100)

 接下来有 N 行, Xi Yi Ri 表示 N 个齿轮的坐标和半径 i=1,2,….,N ( -5000 ≤Xi ,Yi ≤ 5000 3 ≤ Ri ≤ 1000 )

Output

每组测试数据,输出占一行,即所有齿轮转速的绝对值之和 在double范围内,输出整数部分

Examples

input

1
4 32 54
0 30 20
0 0 10
32 54 20
-40 30 20

output

20000

思路 

1、深搜

2、建下图最短路 dijstra跑一下

#define ll long long 
//#define max(a,b) (a)>(b)?(a):(b)
//#define min(a,b) (a)<(b)?(a):(b)
#define clean(a,b) memset(a,b,sizeof(a))// 水印
//std::ios::sync_with_stdio(false);
//  register
const int MAXN=1110;
const int INF32=0x3f3f3f3f;
const ll INF64=0x3f3f3f3f3f3f3f3f;
const int mod=998244353;
const double PI=acos(-1.0);

double x[MAXN],y[MAXN],r[MAXN];
int mp[MAXN][MAXN];
int vis[MAXN],dis[MAXN];
int pre[MAXN];
double smalr=9999999,bigr=9999999;
int n,Si,Ti;

void intt()
{
	clean(dis,INF32);
	clean(vis,0);
	clean(pre,-1);
	clean(mp,INF32);
}

void Djstr()
{
	dis[Si]=0;
	for(int k=1;k<=n;++k)
	{
		int can=-1,minn=INF32;
		for(int i=1;i<=n;++i)
		{
			if(vis[i]==0&&dis[i]<minn)
			{
				can=i;
				minn=dis[i];
			}
		}
		if(can==-1)
			break;
		vis[can]=1;
		//cout<<"can:"<<can<<endl;
		for(int i=1;i<=n;++i)
		{
			if(vis[i]==0&&dis[i]>mp[can][i]+dis[can])
			{
				dis[i]=mp[can][i]+dis[can];
				pre[i]=can;
			}
		}
	}
}

int main()
{
	int T;
	scanf("%d",&T);
	while(T--)
	{
		intt();
		double xt,yt;
		scanf("%d%lf%lf",&n,&xt,&yt);
		for(int i=1;i<=n;++i)
		{
			scanf("%lf%lf%lf",&x[i],&y[i],&r[i]);
			if(x[i]==0&&y[i]==0)
				smalr=r[i],Si=i;
			if(x[i]==xt&&y[i]==yt)
				bigr=r[i],Ti=i;
		}
		for(int i=1;i<=n;++i)
		{
			for(int j=i+1;j<=n;++j)
			{
				if(sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]))+1e-5>r[i]+r[j]
				 &&sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]))-1e-5<r[i]+r[j])
					mp[i][j]=mp[j][i]=1;//齿轮相切,可以连边 
			}
		}
		Djstr();//已知最短路 
		int res=Ti;
		double ans=0;
		while(res!=-1)
		{
			ans+=smalr/r[res];
			res=pre[res];
		}
		ans=10000.0*ans;
		printf("%d\n",int(ans));
	}
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值