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)的主要内容,如果未能解决你的问题,请参考以下文章