zoukankan      html  css  js  c++  java
  • [网络流24题-8]汽车加油行驶问题

    汽车加油行驶问题

    分层图最短路(板子题?总之我不会)

    看着就很MFMC但是实际上并不是QAQ

    看题解第一句话分层就懂了QAQ

    大概就是对于一个平面图有多种情况互相转移,那么我们可以对图进行分层

    比如说这个题显然可以用油量进行分层

    对于几个限制

    1.k条边在建图的时候就是油量-1连边就可以了

    2.b在建图的同时也可以直接连边

    3.加油点的所有出边必须是从油量为k连出去 枚举f(0~k-1)连到这个点的k(相当于加满油)边权为c

    4.建油站直接枚举f的时候边权是a+c即可

    直接上dij或spfa即可(但是spfa他死了)

    附代码。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<queue>
    #define inf 20021225
    #define ll long long
    #define mxn 10001
    using namespace std;
    struct edge{int to,lt,v;}e[1000001];
    struct node
    {
        int x,dis;
        node(){}
        node(int _x,int _dis){x=_x,dis=_dis;}
    };
    bool operator <(node a,node b){return a.dis>b.dis;}
    priority_queue<node> que;
    bool vis[1000001];int in[1000001],n,k,cnt,dis[1000001],a,b,c;
    void add(int x,int y,int v){e[++cnt].to=y;e[cnt].lt=in[x];e[cnt].v=v;in[x]=cnt;}
    int id(int x,int y,int f){return f*n*n+n*(x-1)+y;}
    int dij()
    {
    	memset(dis,48,sizeof(dis));
    	dis[id(1,1,k)]=0;//printf("%d
    ",id(1,1,k));
    	que.push(node(id(1,1,k),0));
    	/**printf("QAQ");*/
    	while(!que.empty())
    	{
    		node cur=que.top();que.pop();
    		if(vis[cur.x])	continue;
    		vis[cur.x]=1;int tmp=dis[cur.x];
    		for(int i=in[cur.x];i;i=e[i].lt)
    		{
    			int y=e[i].to;
    			if(dis[y]>tmp+e[i].v)
    			{
    				dis[y]=tmp+e[i].v;
    				que.push(node(y,dis[y]));
    			}
    		}
    	}
    	int ans=inf;
    	for(int i=0;i<=k;i++)
    	//{
    		ans=min(ans,dis[id(n,n,i)]);
    		//printf("%d %d
    ",i,dis[id(n,n,i)]);
    	//}
    	return ans;
    }
    int mp[101][101];
    int xx[4]={1,-1,0,0},yy[4]={0,0,1,-1};
    int main()
    {
    	scanf("%d%d%d%d%d",&n,&k,&a,&b,&c);
    	for(int i=1;i<=n;i++)
    		for(int j=1;j<=n;j++)	scanf("%d",&mp[i][j]);
    	for(int x=1;x<=n;x++)
    		for(int y=1;y<=n;y++)
    		{
    			int cc=mp[x][y]?0:c;
    			for(int f=0;f<k;f++)
    				add(id(x,y,f),id(x,y,k),a+cc);
    			for(int i=0;i<4;i++)
    			{
    				int dx=x+xx[i],dy=y+yy[i],tmp=(dx<x)|(dy<y);
    				if(dx<1||dy<1||dx>n||dy>n)	continue;
    				if(mp[x][y])	add(id(x,y,k),id(dx,dy,k-1),tmp*b);
    				else
    					for(int f=1;f<=k;f++)
    						add(id(x,y,f),id(dx,dy,f-1),tmp*b);
    			}
    		}
    	printf("%d
    ",dij());
    	return 0;
    }
  • 相关阅读:
    ElasticSearch 查询语法
    自定义的带tab的可左右滑动的viewpager之二viewpager与fragment不兼容
    QT5 串口收发实例代码
    Communications link failure报错的处理
    mac 环境下mysql 不能删除schema问题的解决办法
    [置顶] How to dump redo log entry?
    pjsip视频通信开发(上层应用)之拨号界面整体界面功能实现
    windows command ftp 中文文件名乱码解决方法
    (字符串的模式匹配4.7.18)POJ 2406 Power Strings(求一个字符串的最小重复串)
    通过程序 VB.Net 或 C# 读取文本文件行数
  • 原文地址:https://www.cnblogs.com/hanyuweining/p/10321957.html
Copyright © 2011-2022 走看看