枚举一下选的位置,每次算一下就可以了。
#include<cstdio> #include<cstring> #include<cmath> #include<vector> #include<map> #include<stack> #include<queue> #include<string> #include<algorithm> using namespace std; const int INF=0x7FFFFFFF; const int maxn=1000+100; int n,m,k,ds; struct Edge { int u,v; int dis; }e[20*maxn]; vector<int>g[maxn]; int tot; int flag[maxn],dis[maxn]; double ans1,ans2; int ans; int MIN; int get(char *s) { int num=0; if(s[0]!='G') { for(int i=0;s[i];i++) num=num*10+s[i]-'0'; } else { for(int i=1;s[i];i++) num=num*10+s[i]-'0'; num=num+n; } return num; } void SPFA(int s) { queue<int>Q; memset(flag,0,sizeof flag); for(int i=0;i<=n+m;i++) dis[i]=INF; Q.push(s); flag[s]=1; dis[s]=0; while(!Q.empty()) { int head=Q.front(); Q.pop(); flag[head]=0; for(int i=0;i<g[head].size();i++) { int id=g[head][i]; if(dis[head]+e[id].dis<dis[e[id].v]) { dis[e[id].v]=dis[head]+e[id].dis; if(flag[e[id].v]==0) { flag[e[id].v]=1; Q.push(e[id].v); } } } } } int main() { scanf("%d%d%d%d",&n,&m,&k,&ds); tot=0; for(int i=1;i<=k;i++) { char u[5],v[5]; int dis; scanf("%s%s%d",u,v,&dis); e[tot].u=get(u),e[tot].v=get(v); e[tot].dis=dis; g[get(u)].push_back(tot),tot++; e[tot].u=get(v),e[tot].v=get(u); e[tot].dis=dis; g[get(v)].push_back(tot),tot++; } ans1=1.0*INF; ans2=1.0*INF; MIN=0; for(int i=n+1;i<=n+m;i++) { SPFA(i); int sum=0,MIN_NOW=INF; for(int j=1;j<=n;j++) { if(dis[j]>ds) {sum=-1;break;} else { sum=sum+dis[j]; MIN_NOW=min(MIN_NOW,dis[j]); } } if(sum==-1) continue; if(MIN_NOW>MIN) { MIN=MIN_NOW; ans2=1.0*sum/n; ans1=1.0*MIN; ans=i; } else if(MIN_NOW==MIN&&1.0*sum/n<ans2) { ans2=1.0*sum/n; ans=i; } } if(MIN==0) printf("No Solution\n"); else { printf("G%d\n",ans-n); printf("%.1lf %.1lf\n",ans1,ans2); } return 0; }