zoukankan      html  css  js  c++  java
  • 【YBTOJ】【LOJ 6223】【Luogu P4009】[网络流24题]汽车加油行驶问题

    链接:

    洛谷

    LOJ

    题目大意:

    一辆汽车从 ((1,1))((N,N))

    在若干个网格交叉点处,设置了油库,可供汽车在行驶途中加油。汽车在行驶过程中应遵守如下规则:

    1. 汽车只能沿网格边行驶,装满油后能行驶 (K) 条网格边。出发时汽车已装满油,在起点与终点处不设油库。

    2. 汽车经过一条网格边时,若其 (X) 坐标或 (Y) 坐标减小,则应付费用 (B) ,否则免付费用。

    3. 汽车在行驶过程中遇油库则应加满油并付加油费用 (A)

    4. 在需要时可在网格点处增设油库,并付增设油库费用 (C)(不含加油费用(A) )。

    5. (N,K,A,B,C) 均为正整数, 且满足约束: (2leq Nleq 100,2 leq K leq 10)

    正文:

    众所周知,网络流 24 题都不是网络流。

    本题就在广搜的壳子上套 dij 或 SPFA。

    代码:

    const int N = 110, K = 20;
    
    inline ll Read()
    {
    	ll x = 0, f = 1;
    	char c = getchar();
    	while (c != '-' && (c < '0' || c > '9')) c = getchar();
    	if (c == '-') f = -f, c = getchar();
    	while (c >= '0' && c <= '9') x = (x << 3) + (x << 1) + c - '0', c = getchar();
    	return x * f;
    }
    
    int n, m, A, B, C;
    int a[N][N];
    
    struct node
    {
    	int dis, x, y, k;
    	bool operator < (const node &a) const
    	{
    		return dis > a.dis;
    	}
    };
    
    priority_queue<node> q;
    int dis[N][N][K];
    bool vis[N][N][K];
    
    int dx[5] = {0, -1, 0, 1, 0},
        dy[5] = {0, 0, -1, 0, 1};
    
    void dij(node s)
    {
    	memset (dis, 127 / 3, sizeof dis);
    	memset (vis, 0, sizeof vis);
    	dis[s.x][s.y][s.k] = 0;
    	q.push(s);
    	while (!q.empty())
    	{
    		node u = q.top(); q.pop();
    		if (vis[u.x][u.y][u.k]) continue;
    		vis[u.x][u.y][u.k] = 1;
    		if (a[u.x][u.y] && u.k != m)
    		{
    			if (dis[u.x][u.y][u.k] + A < dis[u.x][u.y][m])
    			{
    				dis[u.x][u.y][m] = dis[u.x][u.y][u.k] + A;
    				q.push((node){dis[u.x][u.y][m], u.x, u.y, m});
    			} 
    			continue;
    		}
    		else
    		{
    			if (dis[u.x][u.y][u.k] + A + C < dis[u.x][u.y][m])
    			{
    				dis[u.x][u.y][m] = dis[u.x][u.y][u.k] + A + C;
    				q.push((node){dis[u.x][u.y][m], u.x, u.y, m});
    			} 
    		}
    		if (u.k > 0)
    			for (int i = 1; i <= 4; i ++)
    			{
    				if (u.x + dx[i] < 1 || u.x + dx[i] > n || u.y + dy[i] < 1 || u.y + dy[i] > n) continue;
    				if (dis[u.x][u.y][u.k] + (i <= 2) * B < dis[u.x + dx[i]][u.y + dy[i]][u.k - 1])
    					{
    						dis[u.x + dx[i]][u.y + dy[i]][u.k - 1] = dis[u.x][u.y][u.k] + (i <= 2) * B;
    						q.push((node){dis[u.x + dx[i]][u.y + dy[i]][u.k - 1], u.x + dx[i], u.y + dy[i], u.k - 1});
    					} 
    			}
    	}
    }
    
    int ans = 1e9;
    
    int main()
    {
    	n = Read(), m = Read(), A = Read(), B = Read(), C = Read();
    	for (int i = 1; i <= n; i++)
    		for (int j = 1; j <= n; j++)
    			a[i][j] = Read();
    	dij ((node){0, 1, 1, m});
    	
    	for (int i = 0; i <= m; i++)
    		ans = min(ans, dis[n][n][i]);
    		
    	printf ("%d
    ", ans);
    	return 0;
    }
    
  • 相关阅读:
    【转】Windows守护进程的一种简单实现
    vim 文本会在末尾自动添加换行 md5文件和数据只不对应
    指向指针的指针的理解和应用
    TinyXML C++解析XML
    加密解密 AES RSA MD5 SHA
    微信支付 php兼容问题
    sublime text 2 php 语法错误检查
    微信支付宝支付
    MySql安装和基本管理
    验证码处理
  • 原文地址:https://www.cnblogs.com/GJY-JURUO/p/14798055.html
Copyright © 2011-2022 走看看