[TCO2013]DirectionBoard
Posted jefflyy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[TCO2013]DirectionBoard相关的知识,希望对你有一定的参考价值。
题意:给一个网格,每个格子有一个方向表示在这个格子上要往哪个方向走,你可以改变某些格子的方向,问最少多少次操作使得从任意格子出发都能回到这个格子
woc这都不会我还是回家种田去吧...
题目的要求是改变某些点的出边使得整个图变成许多环,注意到在满足要求的图中,每个点只有一条入边和一条出边,所以我们对每个格子建两个点代表它的出边和入边,相当于是要找到一组入边和出边的匹配,如果一个入边和出边匹配是原来的方向,那么费用为$0$,否则费用为$1$,跑最小费用最大流即可
#include<stdio.h> #include<string> #include<vector> #include<queue> #include<string.h> using namespace std; const int inf=2147483647; int h[510],nex[3010],to[3010],cap[3010],cos[3010],M=1,S,T; void ins(int a,int b,int c,int d){ M++; to[M]=b; cap[M]=c; cos[M]=d; nex[M]=h[a]; h[a]=M; } void add(int a,int b,int c,int d){ ins(a,b,c,d); ins(b,a,0,-d); } int dis[510],n,sum,cost; bool aug[510]; struct pr{ int x,d; pr(int u=0){x=u;d=dis[u];} }t; bool operator<(pr a,pr b){return a.d>b.d;} priority_queue<pr>q; bool bfs(){ int x,i; memset(dis,63,sizeof(dis)); dis[T]=0; q.push(T); while(!q.empty()){ t=q.top(); q.pop(); x=t.x; if(dis[x]!=t.d)continue; for(i=h[x];i;i=nex[i]){ if(cap[i^1]&&dis[x]-cos[i]<dis[to[i]]){ dis[to[i]]=dis[x]-cos[i]; q.push(to[i]); } } } sum+=dis[S]; for(x=1;x<=n;x++){ for(i=h[x];i;i=nex[i])cos[i]+=dis[to[i]]-dis[x]; } return dis[S]!=dis[0]; } int dfs(int x,int f){ if(f==0)return 0; if(x==T){ cost+=f*sum; return f; } int us=0,i,t; aug[x]=1; for(i=h[x];i;i=nex[i]){ if(!cos[i]&&cap[i]&&!aug[to[i]]){ t=dfs(to[i],min(cap[i],f-us)); cap[i]-=t; cap[i^1]+=t; us+=t; if(us==f)break; } } if(us==f)aug[x]=0; return us; } int costflow(){ do{ do{ memset(aug,0,sizeof(aug)); }while(dfs(S,inf)); }while(bfs()); return cost; } const int g[4][2]={{0,-1},{0,1},{-1,0},{1,0}}; int type(char c){ if(c==‘L‘)return 0; if(c==‘R‘)return 1; if(c==‘U‘)return 2; return 3; } class DirectionBoard{ public: int getMinimum(vector<string>mp){ int n,m,i,j,k,x,y,t; n=mp.size(); m=mp[0].length(); S=n*m*2+1; T=S+1; ::n=T; for(i=0;i<n;i++){ for(j=0;j<m;j++){ add(S,i*m+j+1,1,0); t=type(mp[i][j]); for(k=0;k<4;k++){ x=(i+g[k][0]+n)%n; y=(j+g[k][1]+m)%m; add(i*m+j+1,x*m+y+1+n*m,1,k!=t); } add(i*m+j+1+n*m,T,1,0); } } return costflow(); } }; /* int main(){ vector<string>vt; char s[20]; DirectionBoard cl; while(~scanf("%s",s))vt.push_back(s); printf("%d",cl.getMinimum(vt)); } */
以上是关于[TCO2013]DirectionBoard的主要内容,如果未能解决你的问题,请参考以下文章