hdu2680dijks 法1普通矩阵 法2优先队列+链式前向星

普通矩阵 

#include<bits/stdc++.h>
using namespace std;
#define LOCAL
const int inf=0x3f3f3f3f;
const int maxn=1e3+5;
int n,m,vis[maxn],dir[maxn],g[maxn][maxn];
int main(){
	#ifdef LOCAL
	freopen(".\\in.txt","r",stdin);
	freopen(".\\out.txt","w",stdout);
	#endif
	int s,t,p,q,x;
	while(~scanf("%d%d%d",&n,&m,&t)){
		for(int i=0;i<=n;i++){
			vis[i]=1;dir[i]=inf;
			for(int j=0;j<=n;j++){
				g[i][j]=inf;
			}
		}
		for(int i=0;i<m;i++){
			scanf("%d%d%d",&p,&q,&x);
			g[p][q]=min(x,g[p][q]);
		}
		scanf("%d",&x);
		while(x--){
			scanf("%d",&s);
			g[0][s]=0;
		}
		s=0;
		vis[s]=0;dir[s]=0;
		while(s!=t){
			int minn=inf,nex;
			//加了个辅助起点0 所以0也要算在内。若再加一个辅助终点n+1,则 n+1也要算 
			for(int i=0;i<=n;i++){
				if(g[s][i]!=inf){
					dir[i]=min(dir[i],dir[s]+g[s][i]);
				}
//只要有路就可以更新最短路径。vis只是用来判断要不要更新最近点的,所以while外面的vis[s]置0
				if(dir[i]<minn&&vis[i]){
					minn=dir[i];
					nex=i;
				}
			}
			if(minn==inf) break;
			s=nex;
			vis[s]=0;
		}
		if(s!=t) puts("-1");
		else cout<<dir[t]<<endl;
	}
}

优先队列+链式前向星

#include<bits/stdc++.h>
using namespace std;
const int inf=0x3f3f3f3f;
const int maxn=1005;
const int maxm=21050;
int n,m,s,et,vis[maxn],dis[maxn],cnt;
int head[maxn],e[maxm],c[maxm],nex[maxm];
void creat(int u,int v,int w){
	e[++cnt]=v;
	c[cnt]=w;
	nex[cnt]=head[u];
	head[u]=cnt;
} 
struct node{
	int id,w;
	friend bool operator< (node a,node b){
		return a.w>b.w;
	}
};
priority_queue<node>q;
void dij(){
	s=0;dis[s]=0;
	q.push({0,0});
	while(!q.empty()){//可能一直走不到e,所以不能直接用!vis[e] 
		node cur=q.top();q.pop();
		int u=cur.id;
		if(!vis[u]){
			vis[u]=1;
			for(int i=head[u];i;i=nex[i]){
				int v=e[i],w=c[i];
				if(dis[u]+w<dis[v]){
					dis[v]=dis[u]+w;
					q.push({v,dis[v]});
				}
			}
		}
	}
}
int main(){
	int p,q,t,w;
	while(~scanf("%d%d%d",&n,&m,&et)){
		for(int i=0;i<=n;i++){
			vis[i]=0;dis[i]=inf;head[i]=0; 
		}
		cnt=0;//多组数据建边前cnt清0 
		for(int i=0;i<m;i++){
			scanf("%d%d%d",&p,&q,&t);
			creat(p,q,t); 
			//多条边取最小,链式前向星得用优先队列 
		}
		cin>>w;
		for(int i=1;i<=w;i++){
			scanf("%d",&s);
			creat(0,s,0);
		}
//		vis[s]=1;这句不能有 ,优先队列法写最短路vis[s]在不改!!!! 		
		dij();
		if(dis[et]==inf) cout<<"-1"<<endl;
		else cout<<dis[et]<<endl;		
	}
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值