最大费用最大流
向他能走的方向连边,如果有石头可以选则连一条流量为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 }