• 洛谷3356火星探险问题


    题目链接:火星探险问题

    这一题类似于深海机器人问题

    唯一的区别是这一题的资源不再位于边上而位于点上,由于资源只能开采一次所以需要考虑拆点

    接下来就和那一道问题一样了

    接下来又是喜闻乐见的输出方案了

    我们从源点出发,每一次dfs向东走还是向南走,记录一个当前枚举方案时的流量,当某条边的记录流量与原本应当流的流量相同时则说明不能再从这里走,否则就顺着这里向下dfs

    注意及时return

    #include<iostream>
    #include<string>
    #include<string.h>
    #include<stdio.h>
    #include<algorithm>
    #include<math.h>
    #include<vector>
    #include<queue>
    #include<map>
    using namespace std;
    #define rep(i,a,b) for (i=a;i<=b;i++)
    typedef long long ll;
    #define maxd 1e9+7
    struct node1{
        int from,to,nxt,flow,cost;
    }sq[1001000];
    int k,n,m,head[101000],all=1,flow[100100],pre[100100],s,t,mat[40][40],maxf,
        minc,tot=0,dis[100100],tmpf[100100],ans[100100];
    bool vis[100100];
    
    int read()
    {
        int x=0,f=1;char ch=getchar();
        while ((ch<'0') || (ch>'9')) {if (ch=='-') f=-1;ch=getchar();}
        while ((ch>='0') && (ch<='9')) {x=x*10+(ch-'0');ch=getchar();}
        return x*f;
    }
    
    int num(int x,int y)
    {
        return (x-1)*m+y;
    }
    
    void add(int u,int v,int f,int w)
    {
        all++;sq[all].to=v;sq[all].nxt=head[u];sq[all].cost=w;sq[all].flow=f;head[u]=all;
        all++;sq[all].to=u;sq[all].nxt=head[v];sq[all].cost=-w;sq[all].flow=0;head[v]=all;
    }
    
    void init()
    {
        k=read();m=read();n=read();int i,j;
        s=0;t=n*m*2+1;
        add(s,1,k,0);add(t-1,t,k,0);
        for (i=1;i<=n;i++)
        {
            for (j=1;j<=m;j++)
            {
                mat[i][j]=read();
                if (mat[i][j]==2) add(num(i,j),num(i,j)+n*m,1,-1);
                if (mat[i][j]!=1) add(num(i,j),num(i,j)+n*m,maxd,0);
            }
        }
        for (i=1;i<=n;i++)
        {
            for (j=1;j<=m;j++)
            {
                if (mat[i][j]==1) continue;
                if ((i!=n) && (mat[i+1][j]!=1)) add(num(i,j)+n*m,num(i+1,j),maxd,0);
                if ((j!=m) && (mat[i][j+1]!=1)) add(num(i,j)+n*m,num(i,j+1),maxd,0);
            }
        }
    }
    
    bool spfa()
    {
        queue<int> q;int i;
        for (i=1;i<=t;i++) dis[i]=maxd;dis[s]=0;
        memset(vis,0,sizeof(vis));
        memset(flow,0,sizeof(flow));
        vis[s]=1;q.push(s);flow[s]=maxd;
        while (!q.empty())
        {
            int u=q.front();q.pop();vis[u]=0;
            //cout << u << endl;
            for (i=head[u];i;i=sq[i].nxt)
            {
                int v=sq[i].to;
                if ((sq[i].flow) && (dis[v]>dis[u]+sq[i].cost))
                {
                    dis[v]=sq[i].cost+dis[u];pre[v]=i;
                    flow[v]=min(flow[u],sq[i].flow);
                    if (!vis[v])
                    {
                        vis[v]=1;q.push(v);
                    }
                }
            }
        }
        return (dis[t]!=maxd);
    }
    
    void update()
    {
        int now=t;//cout << 'a' << endl;
        maxf+=flow[t];
        minc+=(flow[t]*dis[t]);
        while (now!=s)
        {
            int tmp=pre[now];
            sq[tmp].flow-=flow[t];
            sq[tmp^1].flow+=flow[t];
            now=sq[tmp^1].to;
        }
    }
    
    void ans_dfs(int x,int y)
    {
        int now=num(x,y),i,to0=num(x+1,y),to1=num(x,y+1);
        for (i=head[now+n*m];i;i=sq[i].nxt)
        {
            if (tmpf[i]>=sq[i^1].flow) continue;
            int v=sq[i].to;
            if (v==to0)
            {
                tmpf[i]++;ans[++tot]=0;
                ans_dfs(x+1,y);
                return;
            }
            else if (v==to1)
            {
                tmpf[i]++;ans[++tot]=1;
                ans_dfs(x,y+1);
                return;
            }
        }
    }
    
    void work()
    {
        while (spfa()) update();
        int i,j;
        memset(tmpf,0,sizeof(tmpf));
        //cout << maxf << endl;
        for (i=1;i<=maxf;i++)
        {
            tot=0;ans_dfs(1,1);
            for (j=1;j<=tot;j++) printf("%d %d
    ",i,ans[j]);
        }
    }
    
    int main()
    {
        init();
        work();
        return 0;
    }
    
  • 相关阅读:
    解决Docker安装慢
    Spring Boot源码分析-启动过程
    Ubuntu安装Docker
    Jenkins搭建
    Hexo搭建静态博客站点
    FactoryBean简介以及Mybatis-Spring应用
    ArrayList源码分析
    Spring AOP-用代理代替繁琐逻辑
    Spring Validation-用注解代替代码参数校验
    Netty学习(4):NIO网络编程
  • 原文地址:https://www.cnblogs.com/encodetalker/p/10182727.html
Copyright © 2020-2023  润新知