zoukankan      html  css  js  c++  java
  • 最短路模板

    (1)无负权边单源最短路 堆优化dijkstra

    #include<cstdio>
    #include<vector>
    #include<queue>
    #define REP(i, a, b) for(int i = (a); i < (b); i++)
    using namespace std;
    
    const int MAXN = 11234;
    struct node
    {
    	int u, w;
    	node(int u = 0, int w = 0) : u(u), w(w) {};
    	bool operator < (const node& rhs) const
    	{
    		return w > rhs.w; //注意这里是大于,因为要小跟堆 
    	}	
    }; 
    vector<node> g[MAXN];
    int d[MAXN], n, m;
    
    int work()
    {
    	priority_queue<node> q;
    	REP(i, 1, n + 1) d[i] = (i == 1 ? 0 : 1e9); //注意这里i等于1的时候为0 
    	q.push(node(1, 0)); //加入一开始的边 
    	
    	while(!q.empty())
    	{
    		node x = q.top(); q.pop();
    		int u = x.u;
    		if(d[u] != x.w) continue;  
    		
    		REP(i, 0, g[u].size())
    		{
    			int v = g[u][i].u, w = g[u][i].w;
    			if(d[v] > d[u] + w)
    			{
    				d[v] = d[u] + w;
    				q.push(node(v, d[v]));
    			}
    		}
    	}
    	return d[n];
    }
    
    int main()
    {
    	scanf("%d%d", &n, &m);
    	while(m--)
    	{
    		int u, v, w;
    		scanf("%d%d%d", &u, &v, &w);
    		g[u].push_back(node(v, w));
    		g[v].push_back(node(u, w));
    	}
    	printf("%d
    ", work());
    	return 0;
    }

    (2)任意两点间最短路 Floyd

    //初始化 
    REP(i, 0, n)
    	REP(j, 0, n)
    		d[i][j] = (i == j ? 0 : 1e9);
    //Floyd
    REP(k, 0, n)
      REP(i, 0, n)
    	REP(j, 0, n)
    	  if(d[i][k] != 1e9 && d[k][j] != 1e9)
    	    d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
    		// d[i][j] |= (d[i][k] && d[k][j]) 判断联通 

    (3)可有负权变单源最短路SPFA(可以用来判断负环)

    #include<cstdio>
    #include<vector>
    #include<queue>
    #define REP(i, a, b) for(int i = (a); i < (b); i++)
    using namespace std;
    
    const int MAXN = 11234;
    struct node
    {
    	int v, w;
    	node(int v = 0, int w = 0) : v(v), w(w) {}
    };
    vector<node> g[MAXN];
    int d[MAXN], vis[MAXN], cnt[MAXN], n, m;
    
    int work()
    {
    	queue<int> q;
    	REP(i, 1, n + 1) d[i] = (i == 1 ? 0 : 1e9);
    	vis[1] = 1;
    	q.push(1);
    	
    	while(!q.empty())
    	{
    		int u = q.front();
    		q.pop(); vis[u] = 0;
    		REP(i, 0, g[u].size())
    		{
    			int v = g[u][i].v, w = g[u][i].w;
    			if(d[v] > d[u] + w)
    			{
    				d[v] = d[u] + w;
    				if(!vis[v])
    				{
    					vis[v] = 1;
    					q.push(v);
    					if(++cnt[v] > n) return -1;//关键!可以判断负环 
    				}
    			}
    		}
    	}
    	
    	return d[n];
    }
    
    int main()
    {
    	scanf("%d%d", &n, &m);
    	while(m--)
    	{
    		int u, v, w;
    		scanf("%d%d%d", &u, &v, &w);
    		g[u].push_back(node(v, w));
    		g[v].push_back(node(u, w));
    	}
    	printf("%d
    ", work());
    	return 0;	
    } 

    其实spfa和dijkstra非常像, dijkstra是每次找一个最近的点入队, 然后去松弛。而spfa是一个点可以入很多次, 每次都去松弛。

  • 相关阅读:
    评审管理小结
    安全性测试入门 (五):Insecure CAPTCHA 验证码绕过
    安全性测试入门 (四):Session Hijacking 用户会话劫持的攻击和防御
    安全性测试入门 (三):CSRF 跨站请求伪造攻击和防御
    测试管理:问题驱动的测试过程改进
    逻辑思维驱动 (测试) 工作管理
    测试管理:用量化的思想管理工作
    软件质量报告模板-产品质量度量
    一篇短文再谈“敏捷”
    Windows XP系列全下载(均为MSDN原版)
  • 原文地址:https://www.cnblogs.com/sugewud/p/9819549.html
Copyright © 2011-2022 走看看