test 零食店 (dp+二分)
?
零食店
snackstore.in?? snackstore.out??
時間限制:1 s?? 內存限制:256 MB
【題目描述】
?? 成功找到了學長之后學姐感覺到有些餓,于是決定去附近的零食店給自己和學長買些零食。
?? 焦作市的有n家零食店,由m條道路連接著這些零食店,每條道路都有自己的長度l,每家零食店都有自己的消費指數。
?? 由于學姐是個窮B,所以去買零食的路上不能經過某些消費指數超過一定限度的店。
?? 同時由于學姐體力有限,所以去買零食的過程中走的路程不能太長。
?? 想來想去學姐決定去問學長買什么零食比較好,反正到最后都是學長吃╮(╯_╰)╭
?? 在去問之前,學姐準備先做好準備,她把焦作市(所有零食店)的地圖給了你,希望你能編出一個程序快速回答她從某個零食店出發,在上述限制下有多少家零食店可供她挑選。
【輸入格式】
?? 第一行三個正整數n,m,q,分別代表零食店數,道路數和詢問數。
?? 接下來一行n個正整數,第i個正整數vi代表第i家零食店的消費指數。
?? 接下來m行,第i行三個正整數x,y,l,代表第i條道路連接編號為x和y的兩個零食店,長度為l。
?? 接下來q行第i行三個正整數s,c,d,代表第i個詢問要求從s出發,所經過的零食店的消費指數不能超過c(除了起點和終點以外),且行走路程不超過d。
【輸出格式】
?? 一共q行,第i行一個整數代表在第i個詢問的要求下有多少家零食店可供學姐挑選。
【樣例輸入】
?
5 5 2
1 2 3 4 5
1 2 1
1 3 4
2 3 2
1 4 3
2 5 1
1 1 3
2 1 2
【樣例輸出】
2
3
【提示】
樣例中第一個詢問能去編號為2/4的零食店。
第二個詢問能去編號為1/3/5的零食店。
對于40%的數據,n≤10,m≤20,q=1。
對于70%的數據,m≤500,q≤10000。
對于100%的數據,n≤100,m≤10000,q≤1000000,vi,c,d≤10^9,1≤x,y,s≤n,l≤10^6。
題解: dp+二分
f[k][i][j]表示中間點為消費指數前k的點,從i到j的最短路徑。
f[k][i][j]=min(f[k-1][i][j],f[k-1][i][id[k]]+f[k-1][id[k]][j])
然后在計算答案的時候二分小于等于c的最后一個位置k,統計f[k][x][i]的答案。
#include<iostream> #include<algorithm> #include<cstring> #include<cstdio> #include<cmath> #define N 203 #define LL long long using namespace std; int n,m,q,val[N],vc[N],id[N]; int dis[N][N][N]; int cmp(int x,int y) {return val[x]<val[y]; } int find(int x) {int l=0; int r=n; int ans=0;while (l<=r) {int mid=(l+r)/2;if (vc[mid]<=x) ans=max(ans,mid),l=mid+1;else r=mid-1;}return ans; } int main() {freopen("snackstore.in","r",stdin);freopen("snackstore.out","w",stdout);scanf("%d%d%d",&n,&m,&q);for (int i=1;i<=n;i++)scanf("%d",&val[i]),vc[i]=val[i];sort(vc+1,vc+n+1);for (int i=1;i<=n;i++) id[i]=i;sort(id+1,id+n+1,cmp);memset(dis,127,sizeof(dis)); int inf=dis[0][0][0];for (int i=1;i<=m;i++) {int x,y,z; scanf("%d%d%d",&x,&y,&z);dis[0][x][y]=dis[0][y][x]=min(dis[0][y][x],z);}for (int i=0;i<=n;i++)for (int j=1;j<=n;j++) dis[i][j][j]=0;for (int k=1;k<=n;k++)for (int i=1;i<=n;i++)for (int j=1;j<=n;j++) {if (i==j) continue;if (dis[k-1][i][id[k]]<inf&&dis[k-1][id[k]][j]<inf)dis[k][i][j]=min(dis[k-1][i][j],dis[k-1][i][id[k]]+dis[k-1][id[k]][j]);else dis[k][i][j]=dis[k-1][i][j];}for (int i=1;i<=q;i++) {int x,len,c; scanf("%d%d%d",&x,&c,&len);int t=find(c);int ans=0;for (int j=1;j<=n;j++) if (j!=x&&dis[t][x][j]<=len) ans++;printf("%d\n",ans);} }
總結
以上是生活随笔為你收集整理的test 零食店 (dp+二分)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 基于java SSM的房屋租赁系统设计和
- 下一篇: 转:基于TLS1.3的微信安全通信协议m