• POJ 3255 Roadblocks (次级短路问题)


    解决方案有许多美丽的地方。让我们跳回到到达终点跳回(例如有两点)。。。。无论如何,这不是最短路,但它并不重要。算法能给出正确的结果

    思考:而最短的路到同一点例程。spfa先正达恳求一次,求的最短路径的再次的相反,然后列举每个边缘<i,j>查找dist_zheng[i] + len<i,j> + dist_fan[j]的第二小值就可以!

    注意不能用邻接矩阵,那样会MLE,应该用邻接表


    /*
    poj    3255
    3808K	266MS
    */
    
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<iostream>
    
    #define MAXN 200005
    #define MAX_INT 2147483647
    
    using namespace std;
    
    int last[5005], dist_1[5005], dist_2[5005], n, m, gra[5005][5005];
    bool mark[MAXN];
    
    struct node
    {
    	int u;
    	int v;
    	int w;
    	int next;
    	node()
    	{
    		u = v = w = next = 0;
    	}
    }edge[MAXN];
    
    void spfa( int dist[5005], int s )
    {
    	queue<int>myQueue;
    	dist[s] = 0;
    	memset(mark, false, sizeof(mark));
    	mark[s] = true;
    	myQueue.push(s);
    	while( !myQueue.empty() )
    	{
    		int x = myQueue.front();
    		myQueue.pop();
    		mark[x] = false;
    		int t = last[x];
    		while( t )
    		{
    			if( dist[ edge[t].v ] > dist[x] + edge[t].w  )
    			{
    				dist[ edge[t].v ] = dist[x] + edge[t].w;
    				if( !mark[ edge[t].v ] )
    					myQueue.push( edge[t].v );
    			}
    			t = edge[t].next;
    		}
    	}
    }
    
    int main()
    {
    	cin >> n >> m;
    	for(int i = 1;i <= m;i ++)
    	{
    		int a, b, c;
    		scanf("%d %d %d", &a, &b, &c);
    		edge[i].u = edge[i + m].v = a;
    		edge[i].v = edge[i + m].u = b;
    		edge[i].w = edge[i + m].w = c;
    		edge[i].next = last[a];
    		last[a] = i;
    		edge[i + m].next = last[b];
    		last[b] = i + m;
    	}
    	memset( dist_1, 1, sizeof(dist_1) );
    	spfa( dist_1, 1 );
    	memset( dist_2, 1, sizeof(dist_2) );
    	spfa( dist_2, n );
    	int ans = MAX_INT, tmp = MAX_INT;
    	for(int i = 1;i <= n;i ++)
    	{
    		int t = last[i];
    		while( t )
    		{
    			if( dist_1[i] + dist_2[ edge[t].v ] + edge[t].w < tmp )
    			{
    				ans = tmp;
    				tmp = dist_1[i] + dist_2[ edge[t].v ] + edge[t].w;
    			}
    			else if( dist_1[i] + dist_2[ edge[t].v ] + edge[t].w < ans 
    					&& dist_1[i] + dist_2[ edge[t].v ] + edge[t].w != tmp )
    				ans = dist_1[i] + dist_2[ edge[t].v ] + edge[t].w;
    			t = edge[t].next;
    		}
    	}
    	cout << ans << endl;
    	return 0;
    }


    版权声明:本文博主原创文章。博客,未经同意不得转载。

  • 相关阅读:
    Wintellect的Power Collections库
    rabbitMQ的几种工作模式
    解决死锁问题
    项目#editormd 的使用
    spring cloud篇#1
    科学#老鼠和毒药
    #杂记#实现一个简单的tomcat
    #栈#leetcode856.括号的分数
    #栈#单调栈#leetCode94.验证栈序列
    #树#遍历#LeetCode37.序列化二叉树
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/4794413.html
Copyright © 2020-2023  润新知