• 网络流24题之火星探险问题


    最大费用最大流

    向他能走的方向连边,如果有石头可以选则连一条流量为1费用为1的边

    dfs输出结果即可。

    By:大奕哥

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 const int N=50,M=2500,inf=1e9;
      4 int n,p,q,ff,s,t,l,cnt=-1,tot;
      5 bool v[M];
      6 int from[M],turn[M],head[M],d[M],m[N][N],pos[N][N],tmp[M];
      7 struct node{
      8     int to,nex,w,from,c;
      9 }e[200005];
     10 void add(int x,int y,int w,int c)
     11 {
     12     e[++cnt].to=y;e[cnt].from=x;e[cnt].c=c;e[cnt].nex=head[x];head[x]=cnt;e[cnt].w=w;
     13     e[++cnt].to=x;e[cnt].from=y;e[cnt].c=-c;e[cnt].nex=head[y];head[y]=cnt;e[cnt].w=0;
     14 }
     15 queue<int>qq;
     16 bool spfa()
     17 {
     18     memset(d,-0x3f,sizeof(d));
     19     memset(v,0,sizeof(v));
     20     d[s]=0;v[s]=1;qq.push(s);
     21     memset(from,-1,sizeof(from));
     22     while(!qq.empty())
     23     {
     24         int x=qq.front();qq.pop();
     25         for(int i=head[x];i!=-1;i=e[i].nex)
     26         {
     27             int y=e[i].to;
     28             if(d[y]>=d[x]+e[i].c||!e[i].w)continue;
     29             d[y]=d[x]+e[i].c;from[y]=i;
     30             if(!v[y])qq.push(y),v[y]=1;
     31         }
     32         v[x]=0;
     33     }
     34     int flow=1e9;
     35     for(int i=from[t];i!=-1;i=from[e[i].from])
     36     flow=min(flow,e[i].w);
     37     if(flow!=1e9)
     38     for(int i=from[t];i!=-1;i=from[e[i].from])
     39     e[i].w-=flow,e[i^1].w+=flow;
     40     if(d[t]<0)return 0;
     41     return 1;
     42 }
     43 void dinic()
     44 {
     45     while(spfa());
     46 }
     47 void dfs(int x,int y)
     48 {
     49     if(x==p&&y==q)return;
     50     int rx=pos[x][y+1],dx=pos[x+1][y],xx=pos[x][y]+tot;
     51     for(int i=head[xx];i!=-1;i=e[i].nex)
     52     {
     53         int yy=e[i].to;
     54         if(tmp[i]>=e[i^1].w)continue;
     55         if(yy==rx)
     56         {
     57             ++tmp[i];
     58             turn[++l]=1;
     59             dfs(x,y+1);
     60             return;
     61         }
     62         if(yy==dx)
     63         {
     64             ++tmp[i];
     65             turn[++l]=0;
     66             dfs(x+1,y);
     67             return;
     68         }
     69     }
     70     return;
     71 }
     72 int main()
     73 {
     74     scanf("%d%d%d",&n,&q,&p);
     75     memset(head,-1,sizeof(head));
     76     for(int i=1;i<=p;++i)
     77     for(int j=1;j<=q;++j)
     78     {
     79         scanf("%d",&m[i][j]);
     80         pos[i][j]=++tot;
     81     }
     82     s=0;t=tot*2+1;
     83     for(int i=1;i<=p;++i)
     84     for(int j=1;j<=q;++j)
     85     {
     86         if(m[i][j]==1)continue;
     87         add(pos[i][j],pos[i][j]+tot,inf,0);
     88         if(m[i][j])
     89         add(pos[i][j],pos[i][j]+tot,1,1);
     90         if(i+1<=p)
     91         add(pos[i][j]+tot,pos[i+1][j],inf,0);
     92         if(j+1<=q)
     93         add(pos[i][j]+tot,pos[i][j+1],inf,0);
     94     }
     95     add(s,1,n,0);add(tot*2,t,n,0);
     96     dinic();
     97     for(int i=1;i<=n;++i)
     98     {
     99         l=0;dfs(1,1);
    100         for(int j=1;j<=l;++j)printf("%d %d
    ",i,turn[j]);
    101     }
    102     return 0;
    103 }
  • 相关阅读:
    js 一维数组转二维数组
    mongoose 系列设置
    手写系列
    设置未登录的导航守卫
    vue 添加设置别名文件
    移动端视口标签
    小程序跳转页面怎么携带数据
    data数据复杂时怎么setData
    小程序注意的点 text标签中一定 不要换行
    小程序用户登录
  • 原文地址:https://www.cnblogs.com/nbwzyzngyl/p/8397821.html
Copyright © 2020-2023  润新知