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

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

開始看題看到“最小最大”,以爲要用二分,有點不敢想象pta也出二分了,看完題並不是,是最短路,看着有點麻煩,不過最近練最短路了。還沒寫就喫午飯了,邊喫邊想這個好麻煩啊。。。
反正這題不算難,就是麻煩,開始還定義二維數組了,也沒必要。這題的關鍵點就是垃圾候選點也可以通過,開始不敢確定,手寫模擬一遍才確定的,剩下的也沒啥,輸入的時候麻煩一點,跑n次最短路就好了,最後再比較一下。段錯誤一次開大內存就對了。

#include<stdio.h>
#include<cstring>
#include<algorithm>
#include<queue>
#include<iostream>
using namespace std;
int inf=0x3f3f3f3f;
const int N=110000;
int dis[N],head[N];
int n,m,num=0;
struct node{
	int to,value,next;
}s[N*2];
void add(int u,int v,int value){
	s[++num].next=head[u];
	s[num].to=v;
	s[num].value=value;
	head[u]=num;
}
void spfa(int x){
	queue<int>q;
	memset(dis,inf,sizeof(dis));
	int i;
	dis[n+x]=0;
	q.push(n+x);	
	while(!q.empty()){
		int t=q.front();
		q.pop();
		for(i=head[t];i;i=s[i].next){
			int to=s[i].to;
			if(dis[to]>dis[t]+s[i].value){
				dis[to]=dis[t]+s[i].value;
				q.push(to);
			}
		}
	}
}
int main()
{
	int x,y,i,j,k,d,v;
	char s1[10],s2[10];
	scanf("%d %d %d %d",&n,&m,&k,&d);
	while(k--){
		scanf("%s %s %d",&s1,&s2,&v);
		if(s1[0]!='G'&&s2[0]!='G'){
			x=y=0;
			for(i=0;s1[i];i++)
				x=x*10+s1[i]-'0';
			for(i=0;s2[i];i++)
				y=y*10+s2[i]-'0';
			add(x,y,v);
			add(y,x,v);
		}
		else if(s1[0]!='G'&&s2[0]=='G'){
			x=0;
			y=n;
			for(i=0;s1[i];i++)
				x=x*10+s1[i]-'0';
			if(strlen(s2)==3) 
				y+=10;
			else y+=s2[1]-'0';
			add(x,y,v);
			add(y,x,v);
		}
		else if(s1[0]=='G'&&s2[0]!='G'){
			x=n;
			y=0;
			if(strlen(s1)==3) 
				x+=10;
			else x+=s1[1]-'0';
			for(i=0;s2[i];i++)
				y=y*10+s2[i]-'0';
			add(x,y,v);
			add(y,x,v);
		}
		else if(s1[0]=='G'&&s2[0]=='G'){
			x=y=n;
			if(strlen(s1)==3) 
				x+=10;
			else x+=s1[1]-'0';
			if(strlen(s2)==3) 
				y+=10;
			else y+=s2[1]-'0';
			add(x,y,v);
			add(y,x,v);
		}
	}
	int ansg,ansm=-inf,ansa=inf;
	for(i=1;i<=m;i++){
		spfa(i);
		int flag=0,a1=inf,a2=0;
		for(j=1;j<=n;j++){
			if(dis[j]>d) {
				flag=1;break;
			}
			if(dis[j]<a1) 
				a1=dis[j];
			a2+=dis[j];
 		}
 		if(!flag){
 			if((ansm<a1)||(ansm==a1&&a2<ansa)){
 				ansg=i;
 				ansm=a1; 
 				ansa=a2;
			 }
		 }
	}
	if(ansa==inf) printf("No Solution");
	else printf("G%d\n%.1f %.1f",ansg,(double)ansm,(double)ansa/n);
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章