解题思路:无非就是一个个垃圾点为起点分别去求最短路。代码从看题到AC花了四十分钟,比赛的时候可能没有那么多时间多
#include<cstdio>
#include<cstring>
#include<set>
#include<iterator>
#include<algorithm>
#include<vector>
#include<queue>
#include<cmath>
using namespace std;
int ma[20],vis[1015],dis[1015];
char t[20];
queue<int> q;
int n,m,d;
const int inf=0x3f3f3f3f;
struct quyu
{
double mi,me;
int fg,u;
}y[15];
struct node
{
int v,d;
node(int v,int d):v(v),d(d){
}
node(){
}
};
vector<node> s[1013];
bool cmp(quyu a,quyu b)
{
if(a.fg==b.fg&&a.mi==b.mi&&a.me==b.me)
return a.u<b.u;
else if(a.fg==b.fg&&a.mi==b.mi)
return a.me<b.me;
else if(a.fg==b.fg)
return a.mi>b.mi;
else
return a.fg>b.fg;
}
int get()
{
int l=strlen(t);
//printf("%d*\n",l);
int v=0,st;
if(t[0]=='G')
st=1;
else
st=0;
for(int i=st;i<l;i++)
{
v=v*10+t[i]-'0';
}
if(st==1) v+=n;
return v;
}
int spfa(int st)
{
node tp,r;
int u;
while(!q.empty()) q.pop();
for(int i=1;i<=n+m;i++) dis[i]=inf;
dis[st]=0;
memset(vis,0,sizeof(vis));
q.push(st);
while(!q.empty())
{
u=q.front();
q.pop();
vis[u]=0;
for(int i=0;i<s[u].size();i++)
{
int v=s[u][i].v,w=s[u][i].d;
if(dis[u]+w<dis[v])
{
dis[v]=dis[u]+w;
if(!vis[v])
{
vis[v]=1;
q.push(v);
}
}
}
}
//for(int i=1;i<=n;i++) printf("%d ",dis[i]);
//printf("\n");
int sum=0,a=inf;
for(int i=1;i<=n;i++)
{
if(dis[i]>d) return 0;
sum+=dis[i];
a=min(a,dis[i]);
}
y[st-n].mi=a;
y[st-n].me=(double)sum/n;
return 1;
}
int main()
{
//freopen("t.txt","r",stdin);
int v,k,w,u;
scanf("%d%d%d%d",&n,&m,&k,&d);
while(k--)
{
scanf("%s",t);
//printf("%c ",t[0]);
u=get();
scanf("%s",t);
//printf("%c \n",t[0]);
v=get();
//printf("%d %d\n",u,v);
scanf("%d",&w);
s[u].push_back(node(v,w));
s[v].push_back(node(u,w));
}
for(int i=1;i<=m;i++)
{
y[i].fg=spfa(n+i);
y[i].u=i;
}
sort(y+1,y+m+1,cmp);
/*for(int i=1;i<=m;i++)
{
printf("u=%d fg=%d mi=%lf me=%lf\n",y[i].u,y[i].fg,y[i].mi,y[i].me);
}*/
if(!y[1].fg)
{
printf("No Solution\n");
}else
{
printf("G%d\n",y[1].u);
printf("%.1lf %.1lf",y[1].mi,round(y[1].me*10)/10);
}
return 0;
}