A類 poj2387Til the Cows Come Home
阿新 • • 發佈:2018-11-16
A類 poj2387Til the Cows Come Home
題意:
一個無向帶權圖有n個頂點,T條邊。頂點序號從1到n。求序號為1的點到序號為n的頂點的最短路。
分析:
注意是無向圖,所以要存兩次邊
這題和B類的那道相似,都用了鏈式前向星及佇列和堆,但是要注意邊和點的輸出位置換了一下
用了鏈式前向星就不用考慮重邊的問題
wa了好多次。。。。。。。。。
程式碼:
#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;
#define maxn 100010
#define maxm 500010
#define INF 0x7fffffff
int head[maxn],cnt,n,m,s,vis[maxn],dis[maxn];
struct Edge{
int u,v,w,next;
}edge[maxm];
struct node{ //堆節點
int w,pos;
bool operator<(const node &x)const{
return w>x.w;
}
};
priority_queue<node>q; //堆
inline void add(int u,int v,int w){ //鏈式前向星
edge[++cnt].u=u;
edge[cnt].v=v;
edge[cnt].w=w;
edge[cnt].next=head[u];
head[u]=cnt;
}
void dijkstra(){
for(int i=1;i<=n;i++){
dis[i]=INF;
}
dis[1]=0; // 賦初值 s到s的距離為0
q.push((node){0,1}); // 把源點扔進堆裡
while(!q.empty()){
node x=q.top(); // 取堆頂
q.pop(); // 彈堆
int u=x.pos;
if(vis[u]) continue;
vis[u]=1;
for(int i=head[u];i;i=edge[i].next){
int v=edge[i].v;
if(dis[v]>dis[u]+edge[i].w){
dis[v]=dis[u]+edge[i].w; // 鬆弛操作
if(!vis[v]){
q.push((node){dis[v],v});
}
}
}
}
}
int main(){
scanf("%d%d",&m,&n); //注意和B類那道題的不同。。。。。。
for(int i=1,x,y,z;i<=m;i++){
scanf("%d%d%d",&x,&y,&z);
add(x,y,z); // 加單向邊
add(y,x,z); // 無向圖加兩次。。。。。。
}
dijkstra();
printf("%d\n",dis[n]);
return 0;
}