最短路

一.dijkstra算法模板:

//dijkstra 
#include<stdio.h>
#include<string.h>
#include<algorithm> 
#define INF 0x3f3f3f
#define max 1000+10
using namespace std;
int visit[max],map[max][max],dist[max],time[max];
int n,m;
int start;
void dijkstra(int start)
{
    int i,j,next;
    int mindist;
    for(i=1;i<=n;i++)
    {
        visit[i]=0;
        dist[i]=map[start][i];
    }
    visit[start]=1;
    for(i=2;i<=n;i++)
    {
        next=i;
        mindist=INF;
        for(j=1;j<=n;j++)
        {
            if(!visit[j]&&mindist>dist[j])
            {
                mindist=dist[j];
                next=j;
            }
        }
        visit[next]=1;
        for(j=1;j<=n;j++)
        {
            if(!visit[j]&&dist[next]+map[next][j]<dist[j])
            dist[j]=dist[next]+map[next][j];
        }
    }
} 
int main()
{
    int i,j,x,y,c,road,end;
    while(scanf("%d%d%d",&n,&m,&start)!=EOF)
    {
        memset(time,INF,sizeof(time));
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=n;j++)
            {
                if(i==j)
                map[i][j]=0;
                else
                map[i][j]=INF;
            }
        }
        while(m--)
        {
            scanf("%d%d%d",&x,&y,&c);
            if(map[y][x]>c)
            map[y][x]=c;
        }
        dijkstra(start);
        scanf("%d",&road);
        for(i=0;i<road;i++)
        {
            scanf("%d",&end);
            time[i]=dist[end];
        }
        sort(time,time+road);
        if(time[0]==INF)
        printf("-1\n");
        else
        printf("%d\n",time[0]);
    } 
    return 0;
}
二.题目模板

1.城市平乱

题目:已知有一个城市发生叛乱,有N个部队维护M个城市的治安。知道城市之间相互到达的时间,N个部队分布在任意N个城市,问一个城市暴乱后,最少需要多长时间有部队营救。

思路:运用dijkstra算法,把暴乱地点当做起点,求出到达每个位置的最短时间,然后再比较一下,所有最短的来。

代码:https://blog.csdn.net/chenzhenyu123456/article/details/43973471

2.find the safest road

题目:已知一个矩阵表示城市建的安全系数,一条从u 到 v 的通道P 的安全度为Safe(P) = s(e1)*s(e2)…*s(ek) e1,e2,ek是P 上的边,输出两个城市间最安全道路的安全系数。

思路:dijkstra算法的模板题,但是要注意 dist[j]=dist[next]*map[next][j];  ,然后全程double

代码:https://blog.csdn.net/chenzhenyu123456/article/details/44118045

3.最短路径+最小花费问题

题目:给你n个点,m条无向边,每条边都有长度d和花费p,给你起点s终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的。

思路:直接在dijkstra算法里改一下模板,当dist[next]+map[next][j]==dist[j]&&money[next]+cost[next][j]<money[j]  时,进行money[j]=money[next]+cost[next][j]; 操作。然后~

代码:https://blog.csdn.net/chenzhenyu123456/article/details/44247177

4.对于数据太大的,map无法存储,可以用链表形式

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const ll LL_INF = 0x3f3f3f3f3f3f3f3f;
const double PI = acos(-1);
const int MAXN = 200009;
int n, m, tot, head[MAXN];
bool vis[MAXN];
ll f[MAXN];
struct Edge
{
	int to, w, nex;
}edge[MAXN * 2];
void init()
{
	tot = 0;
	memset(head, -1, sizeof(head));
}
void addedge(int x, int y, int z)
{
	edge[tot] = {y, z, head[x]};
	head[x] = tot++;
}
void solve()
{
	memset(vis, 0, sizeof(vis));
	memset(f, LL_INF, sizeof(f));
	f[1] = 0;
	queue <int> q;
	q.push(1);
	vis[1] = 1;
	while (!q.empty()) {
		int u = q.front(); q.pop();
		vis[u] = 0;
		for (int i = head[u]; i != -1; i = edge[i].nex) 
        {
			int v = edge[i].to;
			if (f[u] + edge[i].w < f[v]) {
				f[v] = f[u] + edge[i].w;
				if (!vis[v]) {
					q.push(v);
					vis[v] = 1;
				}
			}
		}
	}
}
int main()
{
	while (~scanf("%d %d", &n, &m)) {
		init();
		for (int i = 1; i <= m; ++i) {
			int x, y, z;
			scanf("%d %d %d", &x, &y, &z);
			addedge(x, y, z);
			addedge(y, x, z);
		}
		solve();
		if (f[n] == LL_INF) puts("qwb baka");
		else printf("%lld\n", f[n]);
	}
	return 0;
}
未完待续。。。


猜你喜欢

转载自blog.csdn.net/xianpingping/article/details/79937130