zoukankan      html  css  js  c++  java
  • 【bzoj1579】[Usaco2009 Feb]Revamping Trails 道路升级 分层图最短路

    题目描述

    每天,农夫John需要经过一些道路去检查牛棚N里面的牛. 农场上有M(1<=M<=50,000)条双向泥土道路,编号为1..M. 道路i连接牛棚P1_i和P2_i (1 <= P1_i <= N; 1 <= P2_i<= N). John需要T_i (1 <= T_i <= 1,000,000)时间单位用道路i从P1_i走到P2_i或者从P2_i 走到P1_i 他想更新一些路经来减少每天花在路上的时间.具体地说,他想更新K (1 <= K <= 20)条路经,将它们所须时间减为0.帮助FJ选择哪些路经需要更新使得从1到N的时间尽量少.

    输入

    * 第一行: 三个空格分开的数: N, M, 和 K * 第2..M+1行: 第i+1行有三个空格分开的数:P1_i, P2_i, 和 T_i

    输出

    * 第一行: 更新最多K条路经后的最短路经长度.

    样例输入

    4 4 1
    1 2 10
    2 4 10
    1 3 1
    3 4 100

    样例输出

    1


    题解

    分层图最短路

    dis[i][j]为更新j条路径时1到i的最短距离。

    然后跑分层图最短路。

    网上说正解是堆优化Dijkstra,然而我不太会写,只好搞了一个双端队列优化Spfa才勉强卡时过。

    #include <cstdio>
    #include <cstring>
    #include <utility>
    #include <queue>
    using namespace std;
    deque<pair<int , int> > q;
    int head[50010] , to[100010] , next[100010] , cnt , inq[50010][21];
    long long len[100010] , dis[50010][21];
    void add(int x , int y , long long z)
    {
    	to[++cnt] = y;
    	len[cnt] = z;
    	next[cnt] = head[x];
    	head[x] = cnt;
    }
    int main()
    {
    	int n , m , k , i , j , x , y;
    	long long z , ans = 0x3f3f3f3f3f3f3f3fll;
    	pair<int , int> u , tmp;
    	scanf("%d%d%d" , &n , &m , &k);
    	for(i = 1 ; i <= m ; i ++ )
    		scanf("%d%d%lld" , &x , &y , &z) , add(x , y , z) , add(y , x , z);
    	memset(dis , 0x3f , sizeof(dis));
    	dis[1][0] = 0;
    	q.push_front(make_pair(1 , 0));
    	while(!q.empty())
    	{
    		u = q.front();
    		q.pop_front();
    		x = u.first , y = u.second;
    		inq[x][y] = 0;
    		for(i = head[x] ; i ; i = next[i])
    		{
    			for(j = 0 ; j <= 1 ; j ++ )
    			{
    				if(y + j <= k && dis[to[i]][y + j] > dis[x][y] + len[i] * (j ^ 1))
    				{
    					dis[to[i]][y + j] = dis[x][y] + len[i] * (j ^ 1);
    					if(!q.empty()) tmp = q.front();
    					if(!q.empty() && dis[to[i]][y + j] < dis[tmp.first][tmp.second]) q.push_front(make_pair(to[i] , y + j));
    					else q.push_back(make_pair(to[i] , y + j));
    				}
    			}
    		}
    	}
    	for(i = 0 ; i <= k ; i ++ ) ans = min(ans , dis[n][i]);
    	printf("%lld
    " , ans);
    	return 0;
    }

     

  • 相关阅读:
    6. 模块picklejson andomoszipfile面对对象(类的封装 操作 __init__)
    xlwt模块,(Excel表格)
    5. 迭代器生成器高阶函数推导式内置函数模块(math.time)
    4. 函数参数变量闭包递归
    3. 深浅拷贝/格式化/字符串/列表/字典/集合/文件操作
    2. 运算/循环/字符串操作
    1. 变量/数据类型
    Puppet自动化部署-安装及配置(3)
    Puppet自动化部署-前期环境准备(2)
    Puppet自动化运维-资源介绍篇(4)
  • 原文地址:https://www.cnblogs.com/GXZlegend/p/6485885.html
Copyright © 2011-2022 走看看