zoukankan      html  css  js  c++  java
  • SPFA模版

    const int MAXN = 1005;
    const int INF = 999999;
    int pre[MAXN];
    bool visited[MAXN];
    int dist[MAXN];
    int maps[MAXN][MAXN];
    int n;
    queue<int> Q;
    
    void SPFA(int src)
    {
    	memset(visited, false, sizeof(visited));
    	memset(pre, -1, sizeof(pre));
    	int i;
    	while (!Q.empty())
    	{
    		Q.pop();
    	}
    	for(i = 1 ; i <= n; i++) 
    	{
    		dist[i] = INF;
    	}
    
    	dist[src] = 0;      
    	visited[src] = true;
    	Q.push(src);
    	while(!Q.empty())  
    	{
    		int frontint = Q.front();
    		Q.pop();
    		visited[frontint] = false;
    		for(i = 1;i <= n; i++)  //遍历所有结点 
    		{
    			if(maps[frontint][i] != INF && dist[i] > dist[frontint] + maps[frontint][i])    
    			{
    				dist[i] = dist[frontint] + maps[frontint][i];
    				pre[i] = frontint;             //修改前驱 
    				if(!visited[i])
    				{
    					visited[i] = true;
    					Q.push(i);
    				}
    			}
    		}
    	}
    }
    
    初始化
    
    for (int i = 1; i <= n; i++)
    		{
    			for(int j = 1; j <= n; j++)
    			{
    				if(i == j)
    				{
    					maps[i][j] = 0;
    				}
    				else
    				{
    					maps[i][j] = INF;
    				}
    			}
    		}

    静态邻接表+ SPFA

    const int MAXN = 105;
    const int INF = 999999;
    
    typedef struct Node 
    {
    	int v;//终点位置
    	int value;//权值
    	int next;//同一起点下在edge数组中的位置
    }Node;
    Node edge[10005];//邻接表
    int first[MAXN];//以该点为起点的第一条边在edge数组中的位置
    int n, m; //n点数 m边数
    bool visited[MAXN];
    int dist[MAXN];
    queue<int>Q;
    
    void init()
    {
    	int x, y, value, index;
    	bool flag;
    	memset(first, -1, sizeof(first));
    	index = 1;
    	for (int i = 1; i <= m; i++)
    	{
    		scanf("%d %d %d", &x, &y, &value);
    		flag = false;
    		for (int j = first[x]; j != -1; j = edge[j].next)
    		{
    			if(y == edge[j].v)
    			{
    				if(value < edge[j].value)
    				{
    					edge[j].value = value;
    				}
    				flag = true;
    				break;
    			}
    		}
    		if(flag)
    		{
    			continue;
    		}
    		edge[index].v = y;
    		edge[index].value = value;
    		edge[index].next = first[x];
    		first[x] = index++;
    
    		swap(x, y);
    		edge[index].v = y;
    		edge[index].value = value;
    		edge[index].next = first[x];
    		first[x] = index++;
    	}
    }
    
    
    void SPFA(int Start)
    {
    	while (!Q.empty())
    	{
    		Q.pop();
    	}
    	memset(visited, false, sizeof(visited));
    	for (int i = 1; i <= n; i++)
    	{
    		dist[i] = INF;
    	}
    	dist[Start] = 0;
    	visited[Start] = true;
    	Q.push(Start);
    	while (!Q.empty())
    	{
    		int top = Q.front();
    		Q.pop();
    		visited[top] = false;
    		for (int i = first[top]; i != -1 ; i = edge[i].next)
    		{
    			int e = edge[i].v;
    			if(dist[e] > edge[i].value + dist[top])
    			{
    				dist[e] = edge[i].value + dist[top];
    				if(!visited[e])
    				{
    					Q.push(e);
    					visited[e] = true;
    				}
    			}
    		}
    	}
    }



    hdoj_2544

    最短路

    Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 19731    Accepted Submission(s): 8430


    Problem Description
    在每年的校赛里,所有进入决赛的同学都会获得一件很漂亮的t-shirt。但是每当我们的工作人员把上百件的衣服从商店运回到赛场的时候,却是非常累的!所以现在他们想要寻找最短的从商店到赛场的路线,你可以帮助他们吗?

     

    Input
    输入包括多组数据。每组数据第一行是两个整数N、M(N<=100,M<=10000),N表示成都的大街上有几个路口,标号为1的路口是商店所在地,标号为N的路口是赛场所在地,M则表示在成都有几条路。N=M=0表示输入结束。接下来M行,每行包括3个整数A,B,C(1<=A,B<=N,1<=C<=1000),表示在路口A与路口B之间有一条路,我们的工作人员需要C分钟的时间走过这条路。
    输入保证至少存在1条商店到赛场的路线。
     

    Output
    对于每组输入,输出一行,表示工作人员从商店走到赛场的最短时间
     

    Sample Input
    2 1 1 2 3 3 3 1 2 5 2 3 5 3 1 2 0 0
     

    Sample Output
    3 2
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<map>
    #include<cmath>
    #include<vector>
    #include<algorithm>
    #include<set>
    #include<string>
    #include<queue>
    #include <stack>
    using namespace std;
    #pragma warning(disable : 4996)
    const int MAXN = 1005;
    const int INF = 999999;
    int pre[MAXN];
    bool visited[MAXN];
    int dist[MAXN];
    int maps[MAXN][MAXN];
    int n;
    queue<int> Q;
    
    void SPFA(int src)
    {
    	memset(visited, false, sizeof(visited));
    	memset(pre, -1, sizeof(pre));
    	int i;
    	while (!Q.empty())
    	{
    		Q.pop();
    	}
    	for(i = 1 ; i <= n; i++) 
    	{
    		dist[i] = INF;
    	}
    
    	dist[src] = 0;      
    	visited[src] = true;
    	Q.push(src);
    	while(!Q.empty())  
    	{
    		int frontint = Q.front();
    		Q.pop();
    		visited[frontint] = false;
    		for(i = 1;i <= n; i++)  //遍历所有结点 
    		{
    			if(maps[frontint][i] != INF && dist[i] > dist[frontint] + maps[frontint][i])    
    			{
    				dist[i] = dist[frontint] + maps[frontint][i];
    				pre[i] = frontint;             //修改前驱 
    				if(!visited[i])
    				{
    					visited[i] = true;
    					Q.push(i);
    				}
    			}
    		}
    	}
    }
    
    int main()
    {
    	freopen("in.txt", "r", stdin);
    	int m, a, b, c;
    	while (scanf("%d %d", &n, &m) != EOF)
    	{
    		if(n == 0 && m == 0)
    		{
    			break;
    		}
    		for (int i = 1; i <= n; i++)
    		{
    			for(int j = 1; j <= n; j++)
    			{
    				if(i == j)
    				{
    					maps[i][j] = 0;
    				}
    				else
    				{
    					maps[i][j] = INF;
    				}
    			}
    		}
    		while (m--)
    		{
    			scanf("%d %d %d", &a, &b, &c);
    			if(maps[a][b] > c)
    			{
    				maps[a][b] = c;
    				maps[b][a] = c;
    			}
    		}
    		SPFA(1);
    		cout << dist[n] << endl;
    	}
    	return 0;
    }


  • 相关阅读:
    用Python操纵文件(自动化脚本的第一步)
    关于Numpy Array的使用技巧整理
    有用的在线小工具汇总
    HackerRank刷题之路---Python
    周志华老师《机器学习》复习要点(持续更新)
    Python函数式编程学习笔记
    Supervised Descent Method学习之路(持续更新)
    HackerRank刷题之路之---Algorithm(基于Python2)(持续更新)
    Vim常用命令精简化汇总及Vim的相关配置问题
    在VC++6.0中,如何将多个工程添加到同一个工作区?
  • 原文地址:https://www.cnblogs.com/lgh1992314/p/5835056.html
Copyright © 2011-2022 走看看