zoukankan      html  css  js  c++  java
  • SPFA+寻路(行路难,洛谷2832)

    注意:本博客代码被黑心数据Hack,有空补回来

    啊啊啊这道难题总算是做出来了,首先是帅比浮云的题解发出来一下:http://www.cnblogs.com/fuyun-boy/p/5922742.html

    原题目地址:https://www.luogu.org/problem/show?pid=2832

    题目背景

    小X来到了山区,领略山林之乐。在他乐以忘忧之时,他突然发现,开学迫在眉睫

    题目描述

    山区有n座山。山之间有m条羊肠小道,每条连接两座山,只能单向通过,并会耗费小X一定时间。

    小X现在在1号山,他的目的是n号山,因为那里有火车站。

    然而小X的体力是有限的。他每通过一条羊肠小道,就会变得更疲劳,导致他通过任意一条羊肠小道的时间都增加1。

    输入输出格式

    输入格式:

    第一行两个数,n,m

    第2行到第m+1行,每行3个数A,B,C,表示A、B之间有一条羊肠小道,可以让小X花费C的时间从A移动到B

    输出格式:

    两行 第一行一个数T,表示小X需要的最短时间

    第二行若干个数,用空格隔开,表示小X的移动路线

    例:1 4 2 5表示:小X从1号山开始,移动到4号山,再到2号山,最后到5号山。

    输入输出样例

    输入样例#1:
    5 8
    2 4 2
    5 2 1
    1 2 1
    4 3 2
    1 3 3
    4 5 2
    1 5 8
    3 5 3
    
    输出样例#1:
    7
    1 3 5 
    

    说明

    n<=10000, m<=200000

    数据保证没有多条最短路径

    【题解】

    这道题就是最短路的变体,不过从起点到终点每多走一条边就要多加一点权值。

    比如说原来的权值是6+7+9+3+5,之后的权值就是6+(7+1)+(9+2)+(3+3)+(5+4)了。

    下面的这个是我写的代码。我的解决方法就是加上两个数组,一个是r,一个是tr。

    d数组还是spfa一如既往的d数组,是除去这道题额外的条件的数组。

    tr数组是补充数组(废话),d[i]+tr[i]表示从起点走到这个点的最小花费。

    r[i]是按照从起点走到第i个节点花费d[i]+tr[i]的最短路径时,最后一次的增加值。

    比如说上面的那个6+(7+1)+(9+2)+(3+3)+(5+4),表示一条路径,则这条路径终点节点的r数组的值是4。

    因为走到这里最后一次加上的数字是4。

     pre数组不说了,帅比浮云说了很清楚。。。

    #include <cstdio>
    #include <cstring>
    #include <queue>
    #define mp make_pair
    using namespace std;
    int n,m,h;
    struct edge
    {
    	int v,w;
    	edge*next;
    };
    edge* link[10001];
    int d[10001],r[10001],tr[10001],pre[10001]; 
    bool v[10001];
    void add(int u,int v,int w)
    {
    	edge* p=new edge;
    	p->v=v;
    	p->w=w;
    	p->next=link[u];
    	link[u]=p;
    }
    void del(edge* p)
    {
    	if(p!=NULL)
    	{
    		del(p->next);
    		delete p;
    	}
    }
    void spfa()
    {
    	queue<int>q;
    	memset(d,0x3f,sizeof(d));
    	d[1]=0;
    	q.push(1);
    	v[1]=true;
    	while(!q.empty())
    	{
    		int x=q.front();
    		q.pop();
    		v[x]=false;
    		for(edge* p=link[x];p!=0;p=p->next)
    		{
    			if(d[x]+tr[x]+p->w+r[x]<d[p->v]+tr[p->v])
    			{
    				d[p->v]=d[x]+p->w;
    				tr[p->v]=tr[x]+r[x];
    				r[p->v]=r[x]+1;
    				pre[p->v]=x;
    				if(v[p->v]==false)
    				{
    					v[p->v]=true;
    					q.push(p->v);
    				}
    			}
    		}
    	}
    }
    void print(int n)
    {
    	if(n!=1)
    		print(pre[n]);
    	printf("%d ",n);
    }
    int main()
    {
    	int CO2,H2O,H2CO3;
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=m;i++)
    	{
    		scanf("%d%d%d",&CO2,&H2O,&H2CO3);
    		add(CO2,H2O,H2CO3);
    	}
    	spfa();
    	printf("%d
    ",d[n]+tr[n]);
    	print(n);
    	for(int i=1;i<=n;i++)
    		del(link[i]);
    	return 0;
    }
    

    祝各位NOIP2016 RP++ SCORE++

  • 相关阅读:
    Valid Anagram
    Spiral Matrix II
    Spiral Matrix
    Kth Smallest Element in a BST
    Count Primes
    javascript 判断浏览器
    javascript 数值交换技巧
    EntityFramework 6 分页模式
    JSON.parse 和 JSON.stringify
    CSS z-index
  • 原文地址:https://www.cnblogs.com/oier/p/6036492.html
Copyright © 2011-2022 走看看