题目链接:http://acm.scu.edu.cn/soj/problem.action?id=4542
题意:中文题。
分析:其实这题本身并不是难题,但在比赛中RE了10几次,发现是没初始化tot=0,然后改了以后然后WA了。后来想了两天实在找不到原因,今天在一个学长的帮助下,才明白是数组开小了,因为可能后来越界后访问了合法的地址,所以是WA,不是RE。吃一堑,长一智吧。另外这题比较nice的方法应该是dijkstra,因为他是稠密图。稀疏图用spfa比较好。
code:
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<queue>
#define min(a,b) (a<b?a:b)
using namespace std;
const int MAXV=2e3+10;
const int MAXE=5e6+5;/原来我写的是4e6+5
const int INF=999999999;
int head[MAXV];
int visit[MAXV];
long long d[MAXV];
int xi[MAXV],yi[MAXV];//存储点的坐标
struct edge{int v,next,w;}es[MAXE];
int tol,n,m,k,V;
void init(){
memset(head,-1,sizeof(head));
tol=0;//千万别忘了
}
void addedge(int a,int b,int c){
es[tol].v=b;
es[tol].w=c;
es[tol].next=head[a];
head[a]=tol++;
}
int dis(int x1,int y1,int x2,int y2){
return abs(x1-x2)+abs(y1-y2);
}
bool spfa(int start,int n){
for(int i=0;i<n;++i)
visit[i]=false,d[i]=INF;
queue<int>q;
while(!q.empty())q.pop();
q.push(start);
visit[start]=true;
d[start]=0;
while(!q.empty()){
int no=q.front();q.pop();
visit[no]=false;
for(int i=head[no];i!=-1;i=es[i].next){
int to=es[i].v;
if(d[to]>d[no]+es[i].w){
d[to]=d[no]+es[i].w;
if(!visit[to]){
visit[to]=true;
q.push(to);
}
}
}
}
printf("%lld\n",min(d[1],d[0]));
}
int main(){
int T;scanf("%d",&T);
while(T--){
init();
scanf("%d%d%d",&n,&m,&k);
xi[0]=1,yi[0]=1;//0
xi[1]=n,yi[1]=m;//1
int x0,y0;scanf("%d%d",&x0,&y0);
xi[2]=x0,yi[2]=y0;//2
V=3;
for(int i=0;i<k;++i){
int x1,y1,x2,y2,fee;
scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&fee);
xi[V]=x1,yi[V++]=y1;
xi[V]=x2,yi[V++]=y2;
addedge(V-1,V-2,fee);
addedge(V-2,V-1,fee);
}
for(int i=0;i<V;++i)
for(int j=0;j<i;++j){
if(i==j)continue;
addedge(i,j,dis(xi[i],yi[i],xi[j],yi[j]));
addedge(j,i,dis(xi[i],yi[i],xi[j],yi[j]));
}//构图
spfa(2,V);
}
}