hdu 3832(最短路)

本文介绍了解决HDU 3832问题的算法思路,采用三次SPFA求出三个特定节点到其余各点的最短距离,并通过枚举中间节点来获取这些节点到三个特定节点的最短距离之和,最终计算出所需结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3832

思路:三次spfa求出1,2,3到各点的最短距离,然后枚举中间点到这三点的最短距离之和为ans,最后就是n-ans-1了。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<queue>
 6 using namespace std;
 7 #define MAXN 222
 8 #define inf 1<<30
 9 struct Node{
10     int x,y,r;
11 }node[MAXN];
12 int n;
13 int map[MAXN][MAXN];
14 bool mark[MAXN];
15 int dd1[MAXN];
16 int dd2[MAXN];
17 int dd3[MAXN];
18 
19 bool Judge(int i,int j){
20     int xx=node[i].x-node[j].x;
21     int yy=node[i].y-node[j].y;
22     if(xx*xx+yy*yy<=(node[i].r+node[j].r)*(node[i].r+node[j].r))
23         return true;
24     return false;
25 }
26 
27 void SPFA(int st,int dd[]){
28     memset(mark,false,sizeof(mark));
29     for(int i=1;i<=n;i++)dd[i]=inf;
30     mark[st]=true;
31     dd[st]=0;
32     queue<int>Q;
33     Q.push(st);
34     while(!Q.empty()){
35         int u=Q.front();
36         Q.pop();
37         mark[u]=false;
38         for(int i=1;i<=n;i++){
39             if(map[u][i]&&dd[i]>dd[u]+map[u][i]){
40                 dd[i]=dd[u]+map[u][i];
41                 if(!mark[i]){
42                     mark[i]=true;
43                     Q.push(i);
44                 }
45             }
46         }
47     }
48 }
49 
50 
51 
52 int main(){
53     int _case;
54     scanf("%d",&_case);
55     while(_case--){
56         scanf("%d",&n);
57         for(int i=1;i<=n;i++){
58             scanf("%d%d%d",&node[i].x,&node[i].y,&node[i].r);
59         }
60         memset(map,0,sizeof(map));
61         for(int i=1;i<=n;i++){
62             for(int j=i+1;j<=n;j++){
63                 if(Judge(i,j))map[i][j]=map[j][i]=1;
64             }
65         }
66         SPFA(1,dd1);
67         SPFA(2,dd2);
68         SPFA(3,dd3);
69         int ans=inf;
70         for(int i=1;i<=n;i++){
71             if(dd1[i]!=inf&&dd2[i]!=inf&&dd3[i]!=inf&&dd1[i]+dd2[i]+dd3[i]<ans){
72                 ans=dd1[i]+dd2[i]+dd3[i];
73             }
74         }
75         if(ans<inf){
76             printf("%d\n",n-ans-1);
77         }else 
78             puts("-1");
79     }
80     return 0;
81 }
View Code

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值