PAT天梯赛练习题——L3-005. 垃圾箱分布(暴力SPFA)
?
L3-005. 垃圾箱分布
時間限制 200 ms內存限制 65536 kB
代碼長度限制 8000 B
判題程序 Standard 作者 陳越
大家倒垃圾的時候,都希望垃圾箱距離自己比較近,但是誰都不愿意守著垃圾箱住。所以垃圾箱的位置必須選在到所有居民點的最短距離最長的地方,同時還要保證每個居民點都在距離它一個不太遠的范圍內。
現給定一個居民區的地圖,以及若干垃圾箱的候選地點,請你推薦最合適的地點。如果解不唯一,則輸出到所有居民點的平均距離最短的那個解。如果這樣的解還是不唯一,則輸出編號最小的地點。
輸入格式:
輸入第一行給出4個正整數:N(<= 103)是居民點的個數;M(<= 10)是垃圾箱候選地點的個數;K(<= 104)是居民點和垃圾箱候選地點之間的道路的條數;DS是居民點與垃圾箱之間不能超過的最大距離。所有的居民點從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剛開始題目意思比較難理解:“選在到所有居民點的最短距離最長的地方”。首先知道題目中對答案的限制條件只有一個,那就是最大距離不能超過Ds,那么對在此基礎上篩選下來的候選位置中計算他們各自的到所有居民區的最短距離,比如我G1到1號1米,2號2米,3號3米;G2到1號6米,到2號5米,到3號10米,那么G1的最短就是1米(一號),G2的最短距離就是5米(二號)。
?
以此類推對每一個篩選出來的候選位置都計算對應的min_dx。然后當然此前要對篩選出來的答案存放到數組,然后排序一下。這題比較杯具的是交了N多次,剛開始是用map寫鄰接表,超時,改為vector,終于不超時了,可是總是最后一個組WA,不解,接著改啊改……WA數次之后發現是自定義排序規則里一個變量寫錯了。真的是無語了。原本還以為這題的坑點是不一定1~N的所有點和垃圾桶位置,還搞了個set存放位置,現在看來題目還是比較友好的……
代碼:
#include<iostream> #include<algorithm> #include<cstdlib> #include<sstream> #include<cstring> #include<cstdio> #include<string> #include<deque> #include<stack> #include<cmath> #include<queue> #include<set> #include<map> #define INF 0x3f3f3f3f #define MM(x) memset(x,0,sizeof(x)) using namespace std; typedef long long LL; const int N=10020; typedef pair<int,double> psd; vector<psd>E[1050]; double d[N]; int n,m,k; double ds; inline int bianhao(char s[]) {int len=strlen(s);int r=0;if(s[0]=='G'){for (int i=1; i<len; i++)r=r*10+(s[i]-'0');return 1000+r;} else{for (int i=0; i<len; i++)r=r*10+(s[i]-'0');return r;} } inline void spfa(const int &s,const int &t) {d[s]=0;priority_queue<pair<double,int> >Q;Q.push(pair<double,int>(-d[s],s));while (!Q.empty()){int now=Q.top().second;Q.pop();for (int i=0; i<E[now].size(); i++){int v=E[now][i].first;if(d[v]>d[now]+E[now][i].second){d[v]=d[now]+E[now][i].second;Q.push(pair<double,int>(-d[v],v));}}} } struct info {int s;double aver,sum,minm;info(const int &ss,const double &av,const double &su,const double &mm):s(ss),aver(av),sum(su),minm(mm){}info(){} }; bool cmp(const info &a,const info &b) {if(a.minm!=b.minm)return a.minm>b.minm;//就是這個地方寫成了a.minm>b.sum,強行WA數次- -if(a.aver!=b.aver)return a.aver<b.aver;elsereturn a.s<b.s; } int main(void) {int i,j;while (~scanf("%d%d%d%lf",&n,&m,&k,&ds)){for (i=0; i<1050; i++)E[i].clear();char s[5],t[5];int S,T;double dx;for (i=0; i<k; i++){scanf("%s%s%lf",s,t,&dx);S=bianhao(s);T=bianhao(t);E[S].push_back(psd(T,dx));E[T].push_back(psd(S,dx)); }info ans[1000];int cnt=0;for (i=1; i<=m; i++){memset(d,0x43,sizeof(d));for (j=1; j<=n; j++)spfa(i+1000,j);bool flag=1;double sss=0,tj,mm=1e6;for (j=1; j<=n; j++){tj=d[j];if(tj>ds){flag=0;break;}sss+=tj;if(tj<mm)mm=tj;}if(flag)ans[cnt++]=info(i,sss/n,sss,mm); }if(cnt==0)puts("No Solution");else{sort(ans,ans+cnt,cmp);printf("G%d\n%.1lf %.1lf\n",ans[0].s,ans[0].minm,ans[0].aver);}}return 0; }轉載于:https://www.cnblogs.com/Blackops/p/5766331.html
總結
以上是生活随笔為你收集整理的PAT天梯赛练习题——L3-005. 垃圾箱分布(暴力SPFA)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android bitmap图片处理
- 下一篇: 阿里云centos 6.5 32位安装可