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

噓......發表於2020-11-28

大家倒垃圾的時候,都希望垃圾箱距離自己比較近,但是誰都不願意守著垃圾箱住。所以垃圾箱的位置必須選在到所有居民點的最短距離最長的地方,同時還要保證每個居民點都在距離它一個不太遠的範圍內。

現給定一個居民區的地圖,以及若干垃圾箱的候選地點,請你推薦最合適的地點。如果解不唯一,則輸出到所有居民點的平均距離最短的那個解。如果這樣的解還是不唯一,則輸出編號最小的地點。

輸入格式:
輸入第一行給出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;
}

相關文章