CCF 201409-4 最优配餐 100分(bfs)
Posted 登登登ccc
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CCF 201409-4 最优配餐 100分(bfs)相关的知识,希望对你有一定的参考价值。
题目来源:- 计算机软件能力认证考试系统
刚开始的思路:将每个收货点作为目标点,把送货点全部入队列,进行bfs,每次计算出一个结果,把每次迭代的结果相加得出最后答案。这种思路会导致运行超时,可能因为迭代次数过多。
60分代码:
#include<bits/stdc++.h>
using namespace std;
const int MAX=1000;
int n,m,k,d;
bool visited[MAX+10][MAX+10];
int dirX[]= {-1,1,0,0};
int dirY[]= {0,0,-1,1};
int weight[MAX+10];
struct Map {
int x,y,sum;
Map() {}
Map(int xx, int yy, int s=0):x(xx),y(yy),sum(s) {}
} sell[MAX*MAX+10],buy[MAX*MAX+10],del[MAX*MAX+10];
int BFS(int destx, int desty, int destw) {
queue<Map> q;
memset(visited,false,sizeof(visited)); //每次bfs都重新初始化访问标记数组
for(int i=1; i<=d; i++)
visited[del[i].x][del[i].y]=true;
for(int i=1; i<=m; i++) //每次bfs都要将送货点入队
q.push(sell[i]);
while(!q.empty()) {
Map cur=q.front();
q.pop();
visited[cur.x][cur.y]=true;
if(cur.x==destx && cur.y==desty)
return cur.sum*destw;
for(int i=0; i<4; i++) {
int x=cur.x+dirX[i],y=cur.y+dirY[i];
if(x<1 || x>n || y<1 || y>n || visited[x][y])
continue;
visited[x][y]=true;
q.push(Map(x,y,cur.sum+1));
}
}
return 0;
}
int main() {
cin>>n>>m>>k>>d;
int x,y,w;
for(int i=1; i<=m; i++) {
cin>>x>>y;
sell[i]=Map(x,y);
}
for(int i=1; i<=k; i++) {
cin>>x>>y>>weight[i];
buy[i]=Map(x,y);
}
for(int i=1; i<=d; i++) {
cin>>x>>y;
del[i]=Map(x,y);
}
long long ans=0;
for(int i=1; i<=k; i++)
ans+=BFS(buy[i].x, buy[i].y, weight[i]); //将每次bfs的结果相加得到答案
cout<<ans;
return 0;
}
改进:将所有送货点在输入时就全部入队,使用一个权重数组,记录收货点的权重,不是收货点的权重记为0。这样每次遍历到不是收货点的结点,只会加0,而不是加对应的权重*距离。
100分代码:
#include<bits/stdc++.h>
using namespace std;
const int MAX=1005;
int n,m,k,d;
bool visited[MAX][MAX];
int dirX[]= {-1,1,0,0};
int dirY[]= {0,0,-1,1};
long long weight[MAX][MAX];
struct Map {
int x,y;
long long sum;
Map(int xx, int yy, int s=0):x(xx),y(yy),sum(s) {}
};
queue<Map> q;
long long BFS() {
long long ans=0;
while(!q.empty()) {
Map cur=q.front();
q.pop();
visited[cur.x][cur.y]=true;
for(int i=0; i<4; i++) {
int x=cur.x+dirX[i],y=cur.y+dirY[i];
if(x<1 || x>n || y<1 || y>n || visited[x][y])
continue;
visited[x][y]=true;
ans+=weight[x][y]*(cur.sum+1); //下一个结点不是收货点就加0,是收货点就加权重*距离
q.push(Map(x,y,cur.sum+1));
}
}
return ans;
}
int main() {
ios::sync_with_stdio(false);
cin>>n>>m>>k>>d;
int x,y,w;
for(int i=1; i<=m; i++) {
cin>>x>>y;
q.push(Map(x,y)); //在输入时就全部入队
}
for(int i=1; i<=k; i++) {
cin>>x>>y>>w;
weight[x][y]+=w; //可能有多个收货点在同一坐标,权重要累积计算
}
for(int i=1; i<=d; i++) {
cin>>x>>y;
visited[x][y]=true; //记录不可达结点
}
cout<<BFS();
return 0;
}
以上是关于CCF 201409-4 最优配餐 100分(bfs)的主要内容,如果未能解决你的问题,请参考以下文章