2011 Multi-University Training Contest 1 - Host by HNU&&Earth Hour

这道题木想到竟然可以转发为最短路问题,,让我纠结了近一个下午,,更悲剧的是spfa竟然写错了,,,下面说一下题意,就是在世界日这一天里为了响应号召某大学决定关掉除到图书馆,自习室,寝室的路灯,最后问最多可以关多少路灯,,思路:根据路灯的照射范围判断两个地方是不是相通如果相通就连成边同时把边权设置为1,然后求3次最短路径,,再枚举各个点找到dis1[i]+dis2[i]+dis3[i]最小的那个从而得出最多可以关的路灯。。。

AC代码:

#include<iostream> #include<algorithm> #include<string.h> #include<queue> #include<vector> #define N 201 #define M 0xfffffff using namespace std; typedef struct { int x; int y; int r; }Point; typedef struct { int v; int len; }Node; vector<Node> map[N]; Point t[N]; int dis1[N],dis2[N],dis3[N]; bool visit[N]; int n,i,j; int max(int a,int b) { if(a>b) return a; else return b; } void spfa(int s,int dis[]) { memset(visit,false,sizeof(visit)); for(i=0;i<n;++i) dis[i]=M; dis[s]=0;visit[s]=true; queue<int>Q; Q.push(s); while(!Q.empty()) { int now=Q.front(); Q.pop(); visit[now]=false; int len=map[now].size(); for(i=0;i<len;++i) if(dis[map[now][i].v]>map[now][i].len+dis[now]) { dis[map[now][i].v]=map[now][i].len+dis[now]; if(!visit[map[now][i].v]) { Q.push(map[now][i].v); visit[map[now][i].v]=true; } } } } int main() { int Case; cin>>Case; while(Case--) { cin>>n; for(i=0;i<n;++i) map[i].clear(); for(i=0;i<n;++i) cin>>t[i].x>>t[i].y>>t[i].r; for(i=0;i<n-1;++i) for(j=i+1;j<n;++j) { Node p; int s1=(t[i].x-t[j].x)*(t[i].x-t[j].x)+(t[i].y-t[j].y)*(t[i].y-t[j].y); int s2=(t[i].r+t[j].r)*(t[i].r+t[j].r); if(s1<=s2) { p.v=j; p.len=1; map[i].push_back(p); p.v=i; map[j].push_back(p); } } spfa(0,dis1); spfa(1,dis2); spfa(2,dis3); int ans=-1; for(i=0;i<n;++i) if(dis1[i]<M&&dis2[i]<M&&dis3[i]<M) ans=max(ans,n-(dis1[i]+dis2[i]+dis3[i]+1)); cout<<ans<<endl; }return 0; }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值