L3-005 垃圾箱分布 (30分):最短路

大家倒垃圾的时候,都希望垃圾箱距离自己比较近,但是谁都不愿意守着垃圾箱住。所以垃圾箱的位置必须选在到所有居民点的最短距离最长的地方,同时还要保证每个居民点都在距离它一个不太远的范围内。

现给定一个居民区的地图,以及若干垃圾箱的候选地点,请你推荐最合适的地点。如果解不唯一,则输出到所有居民点的平均距离最短的那个解。如果这样的解还是不唯一,则输出编号最小的地点。

输入格式:
输入第一行给出4个正整数:N(≤10​3)是居民点的个数;M(≤10)是垃圾箱候选地点的个数;K(≤10​4)是居民点和垃圾箱候选地点之间的道路的条数;D​S是居民点与垃圾箱之间不能超过的最大距离。所有的居民点从1到N编号,所有的垃圾箱候选地点从G1到GM编号。

随后K行,每行按下列格式描述一条道路:P1 P2 Dist
其中P1和P2是道路两端点的编号,端点可以是居民点,也可以是垃圾箱候选点。Dist是道路的长度,是一个正整数。

输出格式:
首先在第一行输出最佳候选地点的编号。然后在第二行输出该地点到所有居民点的最小距离和平均距离。数字间以空格分隔,保留小数点后1位。如果解不存在,则输出No Solution。

输入样例1:
4 3 11 5
1 2 2
1 4 2
1 G1 4
1 G2 3
2 3 2
2 G2 1
3 4 2
3 G3 2
4 G1 3
G2 G1 1
G3 G2 2
输出样例1:
G1
2.0 3.3
输入样例2:
2 1 2 10
1 G1 9
2 G1 20
输出样例2:
No Solution
即使不放垃圾箱,那一点也能走。不用四舍五入

//卧槽,最后一个测试样例一直过不去,结果把+0.05去掉就过了,它第一个样例有毒吧 
#include <bits/stdc++.h>
using namespace std;
#define ll long long
int g[1100][1100],dis[10010],b[10010],n,m,k,ds,ans=0,u,v,t,l=0;
double tt,av;
string s;
int ge(int l,int r)
{
    
    
	int tt=0;
	for(int i=l;i<=r;i++)
	 tt=tt*10+s[i]-'0';
	return tt;
}
void sear(int x)
{
    
    
	int tip=n+m;
	for(int i=1;i<=tip;i++)
	{
    
    
		b[i]=0;
		if(g[x][i]) dis[i]=g[x][i];
		else dis[i]=0x3f3f3f3f;
	}
	b[x]=1;dis[x]=0;
	while(1)
	{
    
    
		tt=0x3f3f3f3f;
		for(int i=1;i<=tip;i++)
		 if(b[i]==0&&dis[i]<tt)
		 {
    
    
		 	tt=dis[i];t=i;
		 }
		if(tt==0x3f3f3f3f) break;
		b[t]=1;
		for(int i=1;i<=tip;i++)
		 if(b[i]==0&&g[t][i])
		 dis[i]=min(dis[i],dis[t]+g[t][i]);
	}
	tt=0;t=0x3f3f3f3f;
	for(int i=1;i<=n;i++)
	{
    
    
	 if(dis[i]>ds) 	return;
	 if(dis[i]<t) t=dis[i];
	 tt+=dis[i];
	}
	if(t>l||(t==l&&tt<av)) ans=x,l=t,av=tt;
}
int main()
{
    
    
    ios::sync_with_stdio(false);
    memset(g,0x3f3f3f3f,sizeof(g));
    cin>>n>>m>>k>>ds;
    while(k--)
    {
    
    
    	cin>>s;
    	u=0;v=0;
    	if(s[0]!='G') u=ge(0,s.length()-1);
    	else u=ge(1,s.length()-1)+n;
    	cin>>s;
    	if(s[0]!='G') v=ge(0,s.length()-1);
    	else v=ge(1,s.length()-1)+n;
    	cin>>t;
    	g[u][v]=min(g[u][v],t);
    	g[v][u]=min(g[v][u],t);
	}
	for(int i=1;i<=m;i++)
	 sear(i+n);
	if(ans) cout<<'G'<<ans-n<<endl<<fixed<<setprecision(1)<<(l*1.0)<<" "<<fixed<<setprecision(1)<<av/n;
	else cout<<"No Solution"; 
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43540515/article/details/110258253