• 【网络流24题】汽车加油行驶问题(最短路)


    【网络流24题】汽车加油行驶问题(最短路)

    题面

    Cogs

    题解

    还是SPFA呀。。。
    把剩余的油量直接压进状态里面就好
    额外加一个原地加油的决策就行

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<set>
    #include<map>
    #include<vector>
    #include<queue>
    using namespace std;
    #define MAX 120
    inline int read()
    {
    	int x=0,t=1;char ch=getchar();
    	while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
    	if(ch=='-')t=-1,ch=getchar();
    	while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
    	return x*t;
    }
    struct Line
    {
    	int v,next,w;
    }e[MAX*MAX*MAX];
    int h[MAX*MAX],cnt=1,tot;
    int m[MAX*MAX],g[MAX][MAX],n,K,A,B,C;
    bool vis[MAX*MAX][15];
    inline void Add(int u,int v,int w)
    {
    	e[cnt]=(Line){v,h[u],w};h[u]=cnt++;
    }
    int dis[MAX*MAX][15];
    void SPFA()
    {
    	memset(dis,63,sizeof(dis));
    	dis[g[1][1]][K]=0;
    	queue<int> Q,Q1;
    	Q.push(g[1][1]);Q1.push(K);
    	while(!Q.empty())
    	{
    		int u=Q.front(),t=Q1.front();
    		Q.pop();Q1.pop();
    		if(t!=0)
    		{
    			for(int i=h[u];i;i=e[i].next)
    			{
    				int v=e[i].v,gg=t-1,Dis=dis[u][t]+e[i].w;
    				if(m[v])gg=K,Dis+=A;
    				if(dis[v][gg]>Dis)
    				{
    					dis[v][gg]=Dis;
    					if(!vis[v][gg])vis[v][gg]=true,Q.push(v),Q1.push(gg);
    				}
    			}
    		}
    		int v=u,gg=K,Dis=dis[u][t]+C+A;
    		if(dis[v][gg]>Dis)
    		{
    			dis[v][gg]=Dis;
    			if(!vis[v][gg])vis[v][gg]=true,Q.push(v),Q1.push(gg);
    		}
    		vis[u][t]=false;
    	}
    }
    int main()
    {
    	freopen("trav.in","r",stdin);
    	freopen("trav.out","w",stdout);
    	n=read();K=read();A=read();B=read();C=read();
    	for(int i=1;i<=n;++i)
    		for(int j=1;j<=n;++j)
    			g[i][j]=++tot,m[g[i][j]]=read();;
    	for(int i=1;i<=n;++i)
    		for(int j=1;j<=n;++j)
    		{
    			if(i!=n)Add(g[i][j],g[i+1][j],0);
    			if(j!=n)Add(g[i][j],g[i][j+1],0);
    			if(i!=1)Add(g[i][j],g[i-1][j],B);
    			if(j!=1)Add(g[i][j],g[i][j-1],B);
    		}
    	SPFA();
    	int ans=1e9;
    	for(int i=0;i<=K;++i)ans=min(ans,dis[g[n][n]][i]);
    	printf("%d
    ",ans);
    	return 0;
    }
    
    
  • 相关阅读:
    android源码在线查看
    关于codereview工具与建议
    <转>如何进行code review
    [转] Android实时抓包分析 : 善用adb调试桥
    Swift:UIKit中Demo(一)
    Objective-C学习笔记(十)——循环语句for和do-while的使用
    一些牛人的IOS博客,mark下慢慢学习
    Visual Studio 2015速递(2)——提升效率和质量(VS2015核心竞争力)
    Web前端之基础知识
    通过金矿模型介绍动态规划
  • 原文地址:https://www.cnblogs.com/cjyyb/p/8193340.html
Copyright © 2020-2023  润新知