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

其中P1P2是道路两端点的编号,端点可以是居民点,也可以是垃圾箱候选点。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

 思路:对每一个垃圾箱跑一边DIJ() 。

#include <iostream>
#include <algorithm>
using    namespace std;
const int inf = 999999999;
int   n, m, k, ds, station;
int   e[1020][1020], dis[1020];
bool  vis[1020];
int main() {
    fill(e[0], e[0] + 1020 * 1020, inf);
    fill(dis, dis + 1020, inf);
    scanf("%d%d%d%d", &n, &m, &k, &ds);
    for( int i = 0; i < k; i++) {
         int tempdis;
         string s, t;
         cin >> s >> t >> tempdis;
         int  a, b;
         if(  s[0] == 'G' ) {
              s = s.substr(1);
              a = n + stoi(s);
         } 
		 else a = stoi(s);
         if(  t[0] == 'G') {
              t = t.substr(1); 
              b = n + stoi(t);
         } 
		 else b = stoi(t);
         e[a][b] = tempdis;
         e[b][a] = tempdis;
    }
 int ansid = -1;
 double ansdis = -1, ansaver = inf;
 for( int index = n + 1; index <= n + m; index++) {
      double mindis = inf, aver = 0;
      fill(dis, dis + 1020, inf);
      fill(vis, vis + 1020, false);
      dis[index] = 0;
      for( int i = 0; i < n + m; i++) {
           int u = -1, minn = inf;
           for( int j = 1; j <= n + m; j++) {
                if( vis[j] == false && dis[j] < minn) {
                    u = j;
                    minn = dis[j];
                }
           }
           if( u == -1) 
	           break;
           vis[u] = true;
           for( int v = 1; v <= n + m; v++) {
                if( vis[v] == false && dis[v] > dis[u] + e[u][v] )
                    dis[v] = dis[u] + e[u][v];
           }
      }
     for( int i = 1; i <= n; i++) {
          if( dis[i] > ds) {
              mindis = -1;
              break;
          }
          if( dis[i] < mindis) 
		      mindis = dis[i];
          aver += 1.0 * dis[i];
     }
     if( mindis == -1 )
	     continue;
     aver = aver / n;
     if( mindis > ansdis ) {
         ansid = index;
         ansdis = mindis;
         ansaver = aver;
     } 
	 else if( mindis == ansdis && aver < ansaver ) {
         ansid = index;
         ansaver = aver;
     }
 }
 if( ansid == -1 )
     printf("No Solution");
 else {
     printf("G%d\n", ansid - n);
     printf("%.1f %.1f", ansdis, ansaver);
 }
 return 0; 
}

 

 

#include<iostream>
#include<algorithm>
#include<vector>
#include<cstdio>
using  namespace std;
int    n,m,Ds,mp[3099][3099],ansG=-1;
double minD=-1.0 , avgD=9999999;
int   vis[3009] , dis[3009];
void  dij(  int idx ){
	  fill( vis, vis+3009,0);
	  fill( dis, dis+3009,9999999);
	  dis[idx] = 0;
	  for( int  i=1;i<=n+m;i++){
	  	   int  u = -1 ,minn = 9999999;
		   for( int j=1;j<=n+m;j++){
	  	        if( !vis[j] && dis[j] < minn){
	  	        	 minn = dis[j];
	  	        	 u = j;
				}
		   }
		   if( u == -1 )
               break;
		   vis[u] = 1;
		   for( int j=1;j<=n+m;j++){
		   	    if( dis[j] > dis[u] + mp[u][j] )
		   	        dis[j] = dis[u] + mp[u][j];
		   } 	      
	 }   
	 double  mindd=9999999, avgdd=0;
	 for( int i=1;i<=n;i++ ){ 
	      if( dis[i] > Ds ){ 
		      //cout<<" > Ds"<<endl;
		      return ; 
		  }
		  if( mindd > dis[i] )
		      mindd = dis[i];
	      avgdd+=(double) dis[i];
	 }
	 avgdd = (double)( avgdd/ (double) n );
	 //cout<<"idx : "<<idx-n<<" mindd : "<<mindd<<" avgdd: "<<avgdd<<endl;
	 if( mindd > minD ){
	 	 ansG = idx - n;
	     minD = mindd;
	     avgD = avgdd;
	 }
	 else if( mindd == minD && avgdd < avgD ){
	  	      ansG = idx - n;
	 	      avgD = avgdd  ; 
	 } 
}
int main(void){
	fill(mp[0],mp[0]+3099*3099,9999999);
	int k;
	cin>>n>>m>>k>>Ds;
	
	int aa,bb,d;
	for( int i=1;i<=k;i++){ 
	     string a,b,t;
		 cin>>a>>b>>d;
	     if(  a[0] == 'G' ){ 
	          t = a.substr(1,a.length()-1); 
			  aa = stoi(t)+n; 
		 }
	     else aa = stoi(a);
	     if(  b[0] == 'G' ){
		      t = b.substr(1,b.length()-1); 
			  bb = stoi(t)+n; 
	      }
	     else bb = stoi(b);
	     mp[aa][bb] = mp[bb][aa] = d;
	}
	for( int i=1;i<=m;i++){
		 dij( i+n); 
	}
	if( ansG == -1 ){
		cout<<"No Solution"<<endl;
		return 0 ;
	}
	cout<<"G"<<ansG<<endl;
	printf("%.1f %.1f\n",minD,avgD);
	return 0;
}

 

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 程序猿惹谁了 设计师:白松林 返回首页