使用邻接链表实现的最短路径,头插法写的非常巧妙。
//11342184 c00h00g 2387 Accepted 776K 94MS G++ 2419B 2013-03-12 20:53:55
//POJ 2387 判重边
#include<stdio.h>
#include<stdlib.h>
#define INF 0x7fffffff
using namespace std;
int T,N;
struct Edge{
int id;
Edge* next;
int length;
};
struct Node{
int id;
Edge* firstEdge;
};
Node* nd[1005];
int vis[1005];
int d[1005];
int main(){
while(scanf("%d%d",&T,&N)!=EOF){
int a,b,len;
for(int i=1;i<=N;i++){
nd[i]=new Node;
nd[i]->id=i;
nd[i]->firstEdge=NULL;
vis[i]=0;
d[i]=INF;
}
for(int i=0;i<T;i++){
scanf("%d%d%d",&a,&b,&len);
//查找边是否存在,判重边
bool flag=false;
for(Edge*tmp=nd[a]->firstEdge;tmp!=NULL;tmp=tmp->next){
if(tmp->id==b){
if(tmp->length>len)
tmp->length=len;
flag=true;
break;
}
}
if(!flag){
Edge* edge=new Edge;
edge->id=b;
edge->length=len;
edge->next=nd[a]->firstEdge;
nd[a]->firstEdge=edge;
}
flag=false;
for(Edge*tmp=nd[b]->firstEdge;tmp!=NULL;tmp=tmp->next){
if(tmp->id==a){
if(tmp->length>len)
tmp->length=len;
flag=true;
break;
}
}
if(!flag){
Edge* edge=new Edge;
edge->id=a;
edge->length=len;
edge->next=nd[b]->firstEdge;
nd[b]->firstEdge=edge;
}
}
//数据读完,下面处理,起点为N
for(Edge*tmp=nd[N]->firstEdge;tmp!=NULL;tmp=tmp->next)
d[tmp->id]=tmp->length;
vis[N]=1;
for(int i=0;i<N-1;i++){
int Max=INF,v;
for(int j=1;j<=N;j++){
if(!vis[j]&&d[j]<Max){
Max=d[j];
v=j;
}
}
vis[v]=1;
//更新
for(Edge* tmp=nd[v]->firstEdge;tmp!=NULL;tmp=tmp->next){
if(d[tmp->id]>d[v]+tmp->length&&!vis[tmp->id])
d[tmp->id]=d[v]+tmp->length;
}
}
printf("%d\n",d[1]);
}
//system("pause");
return 0;
}