HDU 3832 Earth Hour (最短路)

Earth Hour

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 125536/65536 K (Java/Others)
Total Submission(s): 1518    Accepted Submission(s): 607


Problem Description
Earth Hour is an annual international event created by the WWF (World Wide Fund for Nature/World Wildlife Fund), held on the last Saturday of March, that asks households and businesses to turn off their non-essential lights and electrical appliances for one hour to raise awareness towards the need to take action on climate change. 
To respond to the event of this year, the manager of Hunan University campus decides to turn off some street lights at night. Each street light can be viewed as a point in a plane, which casts flash in a circular area with certain radius.
What's more, if two illuminated circles share one intersection or a point, they can be regarded as connected.
Now the manager wants to turn off as many lights as possible, guaranteeing that the illuminated area of the library, the study room and the dormitory are still connected(directly or indirectly). So, at least the lights in these three places will not be turned off.
 
Input
The first line contains a single integer T, which tells you there are T cases followed.
In each case:
The first line is an integer N( 3<=N<=200 ), means there are N street lights at total.
Then there are N lines: each line contain 3 integers, X,Y,R,( 1<=X,Y,R<=1000 ), means the light in position(X,Y) can illuminate a circle area with the radius of R. Note that the 1st of the N lines is corresponding to the library, the 2nd line is corresponding to the study room, and the 3rd line is corresponding to the dorm.
 
Output
One case per line, output the maximal number of lights that can be turned off.
Note that if none of the lights is turned off and the three places are still not connected. Just output -1.
 
Sample Input
3
5
1 1 1
1 4 1
4 1 1
2 2 1
3 3 1
7
1 1 1
4 1 1
2 4 1
1 3 1
3 1 1
3 3 1
4 3 1
6
1 1 1
5 1 1
5 5 1
3 1 2
5 3 2
3 3 1
 
Sample Output
-1
2
1
 
Source
 
Recommend
xubiao
 
 
这道题就是在保证寝室,图书馆,自习室都有灯光照射的情况下,问最少保留多少盏灯?
思路不太好想,但是想想是找出能使三个地方连接起来的保留的最少的灯数(路径最短),能不能在路径中找出一个点使之能让其到这三个地方的灯的数量最少(路径最短)
这样的话一开始处理每一个灯,如果两盏灯能有交集或交点,那么两盏灯的权值赋为1
然后处理以寝室,图书馆,自习室为起点,到其他点的最短距离(Difkstra)
最后枚举每一个点,找出到三个地方距离的和最小的点。
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<stdlib.h>
 4 #include<algorithm>
 5 using namespace std;
 6 const int INF=0x3f3f3f3f;
 7 const int MAXN=200+10;
 8 int dis[4][MAXN],w[MAXN][MAXN],vis[MAXN];
 9 struct point
10 {
11     int x,y;
12     int r;
13 }a[MAXN];
14 int n;
15 
16 int distans(int x1,int y1,int x2,int y2)
17 {
18     return (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);
19 }
20 
21 void input()
22 {
23 //    for(int i=0;i<n;i++)
24 //        for(int j=0;j<n;j++)
25 //            w[i][j]=INF;     一直没有想明白为什么这样初始化得不到正确结果
26     memset(w,INF,sizeof(w));
27     scanf("%d",&n);
28     for(int i=0;i<n;i++)
29         scanf("%d %d %d",&a[i].x,&a[i].y,&a[i].r);
30     for(int i=0;i<n;i++)
31     {
32         for(int j=0;j<n;j++)
33         {
34             int temp=distans(a[i].x,a[i].y,a[j].x,a[j].y);
35             if(temp<=(a[i].r+a[j].r)*(a[i].r+a[j].r))//如果两点的距离小于两个圆半径之和,则赋值1
36                 w[i][j]=1;
37         }
38     }
39 }
40 
41 void dijkstra(int s)
42 {
43     memset(vis,0,sizeof(vis));
44     for(int i=0;i<n;i++)
45         dis[s][i]=INF;
46     dis[s][s]=0;
47     for(int i=0;i<n;i++)
48     {
49         int x,temp=INF;
50         for(int j=0;j<n;j++)
51         {
52             if(!vis[j]&&dis[s][j]<temp)
53             {
54                 temp=dis[s][j];
55                 x=j;
56             }
57         }
58         vis[x]=1;
59         for(int i=0;i<n;i++)
60             dis[s][i]=min(dis[s][i],dis[s][x]+w[x][i]);
61     }
62 }
63 
64 int main()
65 {
66     //freopen("in.txt","r",stdin);
67     int kase;
68     scanf("%d",&kase);
69     while(kase--)
70     {
71         input();
72         dijkstra(0);
73         dijkstra(1);
74         dijkstra(2);
75         int ans=INF;
76         for(int i=0;i<n;i++)
77         {
78             if(dis[0][i]!=INF&&dis[1][i]!=INF&&dis[2][i]!=INF)//这个条件还是得要,如果不要的话INF相加会超int
79                 ans=min(ans,dis[0][i]+dis[1][i]+dis[2][i]);
80         }
81         //printf("n=%d
ans=%d
",n,ans);
82         if(ans==INF)
83             printf("-1
");
84         else
85             printf("%d
",n-1-ans);
86     }
87     return 0;
88 }
View Code
原文地址:https://www.cnblogs.com/clliff/p/3905691.html