多源最短距离问题。
对题目的理解:
1.加油站离所有的住房越远越好。
2.所有住房必须在加油站服务范围内。
3.以上条件满足结果不唯一的,取加油站离所有住房的平均距离近的。
4.以上条件满足结果不唯一的,取加油站序号小的。
#include <iostream>
#include <numeric>
#include <algorithm>
using namespace std;
class CA
{
public:
enum{N=1001,M=11,INF=0x6FFFFFFF};
struct node
{
int id,minlen,alllen;
bool operator < (const node& nd) const
{
if(minlen==nd.minlen)
{
if(alllen==nd.alllen) return id<nd.id;
else return alllen<nd.alllen;
}
else return minlen>nd.minlen;
}
};
int n,m,k,ds,ar[N+M][N+M];
node nd[M];
void run();
void dijkstra(int v);
int getid(char *s);
};
int CA::getid(char *s)
{
if(s[0]=='G')
{
s++;
return atoi(s)+n;
}
else return atoi(s);
}
void CA::dijkstra(int v)
{
bool visit[N+M];
fill_n(visit,N+M,false);
int dist[N+M],i,k;
for(i=1;i<=n+m;i++) dist[i]=ar[i][v];
dist[v]=0;
visit[v]=true;
while(1)
{
k=-1;
for(i=1;i<=n+m;i++)
{
if(visit[i]) continue;
if(k==-1||dist[i]<dist[k]) k=i;
}
if(k==-1) break;
visit[k]=true;
for(i=1;i<=n+m;i++)
{
if(visit[i]) continue;
if(dist[i]>dist[k]+ar[k][i])
{
dist[i]=dist[k]+ar[k][i];
}
}
}
nd[v-n].id=v-n;
if(*max_element(dist+1,dist+n+1)>ds) nd[v-n].minlen=-1;
else nd[v-n].minlen=*min_element(dist+1,dist+n+1);
nd[v-n].alllen=accumulate(dist+1,dist+n+1,0);
}
void CA::run()
{
fill_n((int*)ar,(N+M)*(N+M),INF);
scanf("%d%d%d%d",&n,&m,&k,&ds);
char sr1[4],sr2[4];
int r1,r2,d,i;
while(k-->0)
{
scanf("%s%s%d",sr1,sr2,&d);
r1=getid(sr1);
r2=getid(sr2);
ar[r1][r2]=d;
ar[r2][r1]=d;
}
for(i=1;i<=m;i++) dijkstra(n+i);
node *pn=min_element(nd+1,nd+m+1);
if(pn->minlen>0) printf("G%d\n%.1f %.1f\n",pn->id,(double)pn->minlen,(double)pn->alllen/(double)n);
else printf("No Solution\n");
}
int main()
{
//freopen("test.in","r",stdin);
CA *a=new CA;
a->run();
return 0;
}