最短路
#include<bits/stdc++.h>
using namespace std;
const int INF = 1e6;
const int NUM =105;
struct edge{
int from,to,w;//from : 起点 to : 终点 w:权值
edge(int a,int b,int c){from = a;to = b;w = c;}
};
vector<edge>e[NUM];
struct s_node{
int id,n_dis;//id:结点 n_dis:结点到起点的距离
s_node(int b,int c){
id = b;
n_dis = c;
}
bool operator<(const s_node &a)const{
return n_dis>a.n_dis;
}
};
int n,m;
int pre[NUM];//前驱结点
/*void print_path(int s,int t){
if(s==t) {printf("%d",s);return ;}
print_path(s,pre[t]);
printf("%d",t);
}*/
void dijkstra(){
int s = 1;
int dis[NUM]; //记录所有的结点到起点的距离
bool done[NUM];//done[i]=true表示到结点i的最短路径已经找到
for(int i=1;i<=n;i++){dis[i]=INF;done[i]=false;}
dis[s]=0;//起点到自己的距离的为0
priority_queue<s_node>Q;//优先队列储存结点信息
Q.push(s_node(s,dis[s]));//起点先进队
while(!Q.empty()){
s_node u = Q.top();//pop出起点距离最小的结点
Q.pop();
if(done[u.id]) continue;//丢弃找到最短路径的结点,即集合A中的结点
done[u.id] = true;
for(int i=0;i<e[u.id].size();i++){ //检查结点u的所有邻居
edge y = e[u.id][i]; //u.id的第i个邻居是y.to
if(done[y.to]) continue; //丢弃已经找到最短路径的邻居结点
if(dis[y.to]>y.w+u.n_dis){
dis[y.to] = y.w +u.n_dis;
Q.push(s_node(y.to,dis[y.to]));
//扩展新的邻居结点,放到优先队列中
//pre[y.to] = u.id;
//如果有需要就记录路径
}
}
}
printf("%d\n",dis[n]);
//print_path(s,n);
}
int main(){
while(cin>>n>>m){
if(n==0&&m==0) return 0;
for(int i = 1;i <= n;i++) e[i].clear();
while(m--){
int a,b,c;
cin>>a>>b>>c;
e[a].push_back(edge(a,b,c));//a结点的邻居全放在e[a]
e[b].push_back(edge(b,a,c));
}
dijkstra();
}
}
/*5 6
1 2 2
1 3 3
1 4 3
3 5 3
4 5 2
2 5 6
*/ 题意:有n个点,求1到其他所有点的最短路之和加上所有点到1号点的最短路之和
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll INF = 1e9;
const ll NUM =1000005;
struct edge{
int to,next,w;//i就是起点,to是终点,next下一条边,w权值
}edge[NUM],edge2[NUM];
struct s_node{
int id,n_dis;//id:结点 n_dis:结点到起点的距离
s_node(int b,int c){
id = b;
n_dis = c;
}
bool operator<(const s_node &a)const{
return n_dis>a.n_dis;
}//路径小的先出队
};
int n,m,cnt,cnt1;
int head[NUM],head1[NUM];
int pre[NUM];//前驱结点
/*void print_path(int s,int t){
if(s==t) {printf("%d",s);return ;}
print_path(s,pre[t]);
printf("%d",t);
}*/
void addedge(int u,int v,int w){
edge[cnt].to=v;
edge[cnt].w=w;
edge[cnt].next=head[u];
head[u]=cnt++;
}//链式前向星存图
void addedge2(int u,int v,int w){
edge2[cnt1].to=v;
edge2[cnt1].w=w;
edge2[cnt1].next=head1[u];
head1[u]=cnt1++;
}
ll dis[NUM]; //记录所有的结点到起点的距离
bool done[NUM];//done[i]=true表示到结点i的最短路径已经找到
ll dijkstra(int s){
for(int i=1;i<=n;i++){dis[i]=INF;done[i]=false;}
dis[s]=0;//起点到自己的距离的为0
priority_queue<s_node>Q;//优先队列储存结点信息
Q.push(s_node(s,dis[s]));//起点先进队
while(!Q.empty()){
int u = Q.top().id;//pop出起点距离最小的结点
Q.pop();
if(done[u]) continue;//丢弃找到最短路径的结点,即集合A中的结点
done[u] = true;
for(int i=head[u];~i;i=edge[i].next){ //利用head回溯,检查结点u的所有邻居
int y = edge[i].to,w=edge[i].w;//u.id的第i个邻居是y.to
if(done[y]) continue; //丢弃已经找到最短路径的邻居结点
if(dis[y]>dis[u]+w){
dis[y] = dis[u]+w;
Q.push(s_node(y,dis[y]));
//扩展新的邻居结点,放到优先队列中
//pre[y.to] = u.id;
//如果有需要就记录路径
}
}
}
ll sum=0;
for(int i=1;i<=n;i++) sum+=dis[i];
return sum;
}
ll dijkstra1(int s){
for(int i=1;i<=n;i++){dis[i]=INF;done[i]=false;}
dis[s]=0;//起点到自己的距离的为0
priority_queue<s_node>Q;//优先队列储存结点信息
Q.push(s_node(s,dis[s]));//起点先进队
while(!Q.empty()){
int u = Q.top().id;//pop出起点距离最小的结点
Q.pop();
if(done[u]) continue;//丢弃找到最短路径的结点,即集合A中的结点
done[u] = true;
for(int i=head1[u];~i;i=edge2[i].next){ //利用head回溯,检查结点u的所有邻居
int y = edge2[i].to,w=edge2[i].w;//u.id的第i个邻居是y.to
if(done[y]) continue; //丢弃已经找到最短路径的邻居结点
if(dis[y]>dis[u]+w){
dis[y] = dis[u]+w;
Q.push(s_node(y,dis[y]));
//扩展新的邻居结点,放到优先队列中
//pre[y.to] = u.id;
//如果有需要就记录路径
}
}
}
ll sum=0;
for(int i=1;i<=n;i++) sum+=dis[i];
return sum;
}
int main(){
int t;
cin>>t;
while(t--){
memset(head,-1,sizeof(head));
memset(head1,-1,sizeof(head1));
cnt=cnt1=0;
cin>>n>>m;
for(int i = 1;i<=m;i++){
int u,v,w;
cin>>u>>v>>w;
addedge(u,v,w);
addedge2(v,u,w);
}
printf("%lld\n",dijkstra(1)+dijkstra1(1));
}
}hdu2544 最短路
链式前向星
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const ll mod = 1e9 + 7;
const ll N = 1e4 + 7;
int Next[N] , to[N] , head[N] , val[N];
int dis[N] , done[N];
int tot;
struct node{
int u , n_dis;
node(int a, int b){u = a , n_dis = b;}
bool operator<(const node& a) const{
return n_dis > a.n_dis;
}
};
void addedge(int u , int v ,int w){
to[++tot] = v;
val[tot] = w;
Next[tot] = head[u];
head[u] = tot;
}
int n , m;
void dijstra(int s){
memset(dis, 0x3f3f3f3f , sizeof(dis));
memset(done , 0 ,sizeof(done));
priority_queue<node>q;
dis[s] = 0;//到自己的距离为0
q.push({s , dis[s]});
while(q.size()){
int u = q.top().u; q.pop();
if(done[u]) continue;
done[u] = 1;
for(int i = head[u] ; i ; i = Next[i]){
int v = to[i] , w = val[i];
if(done[v]) continue;
if(dis[v] > dis[u] + w){
dis[v] = dis[u] + w;
q.push({v , dis[v]});
}
}
}
cout<<dis[n]<<endl;
}
int main()
{
while(~scanf("%d%d" , &n , &m)){
if(n == 0 && m == 0) break;
tot = 0;
memset(Next, 0, sizeof(Next));
memset(head, 0, sizeof(head));
for(int i = 1; i <= m ; i++){
int u , v ,w;
cin>>u>>v>>w;
addedge(u , v , w);
addedge(v , u , w);
}
dijstra(1);
}
return 0;
}
图论 文章被收录于专栏
难顶