您的位置:首页 > 其它

Wannafly交流赛1 迷宫2 多源最短路

2018-03-11 09:15 369 查看
https://www.nowcoder.com/acm/contest/69#question

解题思路:

n和m只有500,一开始以为是n^2的dp

后来在纸上画了一下,能把两个端点隔开的障碍连起来就是一条由左下边界走到右上边界的路径。 要使路径花费最小。

这样就是一个很简单的多源最短路了。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
typedef long long LL;
int dirx[4]={1,-1,0,0};
int diry[4]={0,0,1,-1};
class Node{
public:
int i,j;
long long w;
bool operator < (const Node &b) const{
return w>b.w;
}
Node(int i,int j,LL w):i(i),j(j),w(w){}
};
int n,m;
LL maps[505][505];
LL dis[505][505];
void dij(){
priority_queue<Node> PQ;
for(int i=2;i<=n;i++){
if(maps[i][1]!=0)
PQ.push(Node(i,1,max(0ll,maps[i][1])));
}
for(int i=1;i<m;i++){
if(maps
[i]!=0)
PQ.push(Node(n,i, max(0ll,maps
[i])));
}
while(!PQ.empty()){
Node now=PQ.top();
PQ.pop();
//cout<<now.i<<","<<now.j<<":"<<now.w<<endl;
if(now.i==1 || now.j==m){
printf("%lld\n",now.w);
return;
}
for(int i=0;i<4;i++){
Node next(now.i+dirx[i],now.j+diry[i],0);
if(next.i<1 || next.j<1 || next.i>n || next.j>m) continue;
if(next.i==1 && next.j==1)
continue;
if(next.i==n && next.j==m)
continue;
//cout<<"maps:"<<maps[next.i][next.j]<<endl;
if(maps[next.i][next.j]!=0){
next.w=now.w+max(0ll,maps[next.i][next.j]);
if(dis[next.i][next.j]>next.w){
PQ.push(next);
dis[next.i][next.j]=next.w;
}
}
}
}
cout<<-1<<endl;
}
int main(){
int Q;
scanf("%d %d %d",&Q,&n,&m);
while(Q--){
memset(dis,0x3f,sizeof dis);
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
scanf("%lld",&maps[i][j]);
}
}
dij();
}
}


想起自己还有一个博客,咳咳,努力刷题。。。。

acm 菜是原罪啊!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: