zoukankan      html  css  js  c++  java
  • 汽车加油行驶问题

    题面

    传送门
    (略)

    sol

    前言:
    此题主要的思想启发在于 用分层图来满足固定限制

    正文:

    考虑到k特别小,可以对于油量的不同状态分别建图,以此来控制运行距离
    因此不妨将第1层作为满油,第k+1层作为空油, 注意初始状态一定是满油,而结束状态不确定
    因此将S连向第一层(1,1),每一层(n,n)都连向T
    行驶: 1~k每层中的非油库点都向其可到达的(下一层)每个点连边,费用易得
    加油(已有油站): 2~k+1中每一层油站的点,都向第一层该点连边,表示油量状态的变化,费用为A
    设置油站 : 对于2~k+1中每个非油站的点向第1层同点连费用为A+C的边
    最后最小费用最大流即可

    code

    #include<bits/stdc++.h>
    using namespace std;
    #define re register
    #define in inline
    #define get getchar()
    #define ll long long
    in int read()
    {
        int t=0; char ch=get;
        while(ch<'0' || ch>'9') ch=get;
        while(ch<='9' && ch>='0') t=t*10+ch-'0', ch=get;
        return t;
    }
    #define int ll
    const int _=4e5+23;
    const int inf=0x3f3f3f3f3f3f3f3f;
    int tot=1, S, T, h[_], n, k, A, B, C, f[110][110];
    struct edge{
        int to,ne,w,val;
    }e[_<<5];
    in void add(int x,int y,int z,int w)
    {
        e[++tot].ne=h[x], e[tot].to=y, e[tot].w=z, e[tot].val=w, h[x]=tot;
        e[++tot].ne=h[y], e[tot].to=x, e[tot].w=0, e[tot].val=-w, h[y]=tot;
    }
    int dis[_], cur[_], vis[_];
    in int bfs()
    {
        memset(vis,0,sizeof(vis));
        memset(dis,0x3f,sizeof(dis));
        queue<int >q;
        q.push(S); dis[S]=0;
        while(!q.empty())
        {
            int u=q.front(); q.pop();
            cur[u]=h[u];vis[u]=0;
            for(re int i=h[u];i;i=e[i].ne)
            {
                int v=e[i].to;
                if(dis[v]>dis[u]+e[i].val && e[i].w)
                {
                    dis[v]=dis[u]+e[i].val;
                    if(!vis[v]){ vis[v]=1; q.push(v);}
                }
            }
        }
        return dis[T]!=inf;
    }
    ll cost=0;
    in int dfs(int u,int flow)
    {
        if(u==T || !flow) return flow;
        int used=0, d; vis[u]=1;
        for(re int i=cur[u];i;i=e[i].ne)
        {
            int v=e[i].to; cur[u]=i;
            if(!vis[v] && e[i].w && dis[v]==dis[u]+e[i].val)
            {
                d=dfs(v,min(flow-used,e[i].w));
                if(!d) continue;
                used+=d, e[i].w-=d, e[i^1].w+=d, cost+=1ll*d*e[i].val;
                if(used==flow) break;
            }
        }
        return used;
    }
    int maxflow;
    in void dinic()
    {
        int qwe;
        while(bfs())
            while(memset(vis,0,sizeof(vis)) && (qwe=dfs(S,inf)));
    }
    in int id(int k,int x,int y) //第k层,(x,y)点的标号
    {
        return (k-1)*n*n+(x-1)*n+y;
    }
    int num(int x,int y) { return id(1,x,y);}
    #define link add
    signed main()
    {
    #ifndef ONLINE_JUDGE
        freopen("1.in","r",stdin);
    #endif
        n=read(),k=read(), A=read(), B=read(), C=read(), S=n*n*(k+1)+1, T=S+1;
        for(re int i=1;i<=n;++i)
            for(re int j=1;j<=n;++j) f[i][j]=read();
        for(re int q=1;q<=k+1;++q){
            add(id(q,n,n),T,1,0);
            for(re int i=1;i<=n;++i)
                for(re int j=1;j<=n;++j)
                {
                    int tt=q+1;
                    if(q==1 || (q<=k && f[i][j]==0))
                    {
                        if(i+1<=n) add(id(q,i,j),id(tt,i+1,j),inf,0);
                        if(j+1<=n) add(id(q,i,j),id(tt,i,j+1),inf,0);
                        if(i-1>=1) add(id(q,i,j),id(tt,i-1,j),inf,B);
                        if(j-1>=1) add(id(q,i,j),id(tt,i,j-1),inf,B);
                    }
                    if(q>1) add(id(q,i,j),id(1,i,j),1,A+C);
                    if(q>1 && f[i][j]) add(id(q,i,j),id(1,i,j),inf,A);
                }
        }
        add(S,id(1,1,1),1,0);
        dinic();
        cout<<cost<<endl;
        return 0;
    }
    
    
    嗯,就这样了...
  • 相关阅读:
    2017年5月19日13:58:17 问题记录
    2017年5月17日20:14:29 rabbitmq 消费 异常信息无法处理 导致轮询
    2017年5月12日15:10:46 rabbitmq不支持非阻塞调用服务器
    2017年5月11日17:43:06 rabbitmq 消费者队列
    2017年5月10日16:11:28 定义所有问题
    MyBatis Plus 只插入只有自增id字段的表
    Centos 7 关闭报警音
    关于git项目切换远程提交路径和提交仓库
    IDEA通过git回滚到某个提交节点或某个版本
    IDEA使用@Autowired注解报错解决方案
  • 原文地址:https://www.cnblogs.com/yzhx/p/14615166.html
Copyright © 2011-2022 走看看