1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
| #include <bits/stdc++.h> #define ll long long using namespace std; const ll inf=1e18,N=5e3+10,M=5e4+10; inline 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-48;ch=getchar();} return x*f; } ll e_cnt=1,head[N]; struct EDGE{ll from,to,w,c,pre;}e[M<<1]; ll n,p,q,s,t,ans,cost; ll dis[N],pre[N]; inline void add(ll from,ll to,ll w,ll c){ e[++e_cnt]=(EDGE){from,to,w,c,head[from]}; head[from]=e_cnt; } inline void add_edge(ll u,ll v,ll w,ll c){ add(u,v,w,c),add(v,u,0,-c); } inline int A(int x,int y){return (x-1)*p+y;} inline int B(int x,int y){return A(x,y)+p*q;}
bool spfa(ll s,ll t){ bool inq[N]; memset(pre,-1,sizeof(pre)); for(int i=1;i<=t;i++)dis[i]=inf,inq[i]=0; queue<ll>que; dis[s]=0,inq[s]=1,que.push(s); while(!que.empty()){ ll u=que.front(); que.pop(); inq[u]=0; for(int i=head[u];i;i=e[i].pre){ if(e[i].w>0){ ll v=e[i].to,c=e[i].c; if(dis[u]+c<dis[v]){ dis[v]=dis[u]+c; pre[v]=i; if(!inq[v]){ que.push(v); inq[v]=1; } } } } } return dis[t]!=inf; } void mincost(ll s,ll t){ while(spfa(s,t)){ ll v=t,flow=inf; while(pre[v]!=-1){ ll i=pre[v],u=e[i].from; flow=min(flow,e[i].w); v=u; } v=t; while(pre[v]!=-1){ ll i=pre[v],u=e[i].from; e[i].w-=flow; e[i^1].w+=flow; v=u; } cost+=dis[t]*flow; ans+=flow; } }
void put_ans(int a){ int x=1,y=1; while(1){ if(x>=q&&y>=p)return; int u=B(x,y); for(int i=head[u];i;i=e[i].pre){ int v=e[i].to; if(!e[i^1].w)continue; if(v==A(x+1,y)){x++,e[i^1].w--,printf("%d 0\n",a);break;} if(v==A(x,y+1)){y++,e[i^1].w--,printf("%d 1\n",a);break;} } } } int main(){ n=read(),p=read(),q=read(); s=p*q*2+1,t=s+1; for(int i=1;i<=q;i++){ for(int j=1;j<=p;j++){ int x; x=read(); if(x!=1){ add_edge(A(i,j),B(i,j),inf,0); if(i+1<=q)add_edge(B(i,j),A(i+1,j),inf,0); if(j+1<=p)add_edge(B(i,j),A(i,j+1),inf,0); if(x==2)add_edge(A(i,j),B(i,j),1,-1); } } } add_edge(s,A(1,1),n,0); add_edge(B(q,p),t,n,0); mincost(s,t); for(int i=1;i<=ans;i++)put_ans(i); return 0; }
|