博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
bzoj3171: [Tjoi2013]循环格(费用流)
阅读量:6843 次
发布时间:2019-06-26

本文共 2486 字,大约阅读时间需要 8 分钟。

 

其实这题的建图并不难(虽然我并没有想出来)

首先,每一个点的入度和出度必须为$1$

那么我们考虑拆点

每个点的出度点向它能到达的点的入度点连边,容量$1$,如果方向为原来的方向则费用$0$否则费用$1$

然后源点向所有入度点连边,所有出度点向汇点连边

因为费用流首先是最大流,所以肯定能跑满

那么最小费用就是答案了

1 //minamoto 2 #include
3 #include
4 #include
5 #include
6 #define inf 0x3f3f3f3f 7 using namespace std; 8 const int N=505,M=100005; 9 int head[N],Next[M],ver[M],edge[M],cost[M],tot=1;10 inline void add(int u,int v,int e,int c){11 ver[++tot]=v,Next[tot]=head[u],head[u]=tot,edge[tot]=e,cost[tot]=c;12 ver[++tot]=u,Next[tot]=head[v],head[v]=tot,edge[tot]=0,cost[tot]=-c;13 }14 int dis[N],vis[N],cur[N],S,T,ans;15 queue
q;16 bool spfa(){17 memset(dis,-1,sizeof(dis));18 memset(vis,0,sizeof(vis));19 memcpy(cur,head,sizeof(int)*(T-S+1));20 q.push(T),dis[T]=0,vis[T]=1;21 while(!q.empty()){22 int u=q.front();q.pop();vis[u]=0;23 for(int i=head[u];i;i=Next[i])24 if(edge[i^1]){25 int v=ver[i],c=cost[i];26 if(dis[v]<0||dis[v]>dis[u]-c){27 dis[v]=dis[u]-c;28 if(!vis[v]) vis[v]=1,q.push(v);29 }30 }31 }32 return ~dis[S];33 }34 int dfs(int u,int limit){35 if(u==T||!limit) return limit;36 int flow=0,f;vis[u]=1;37 for(int i=cur[u];i;cur[u]=i=Next[i]){38 int v=ver[i];39 if(dis[v]==dis[u]-cost[i]&&!vis[v]&&(f=dfs(v,min(limit,edge[i])))){40 flow+=f,limit-=f;41 edge[i]-=f,edge[i^1]+=f;42 ans+=f*cost[i];43 if(!limit) break;44 }45 }46 vis[u]=0;47 return flow;48 }49 void zkw(){50 while(spfa()) dfs(S,inf);51 }52 int id[N][N],c[N],n,m;char s[N];53 int dx[]={
0,0,-1,1},dy[]={-1,1,0,0};54 int main(){55 //freopen("testdata.in","r",stdin);56 c['L']=0,c['R']=1,c['U']=2,c['D']=3;57 scanf("%d%d",&n,&m);58 S=0,T=n*m*2+1;59 for(int i=1;i<=n;++i)60 for(int j=1;j<=m;++j)61 id[i][j]=(i-1)*m+j;62 for(int i=1;i<=n;++i){63 scanf("%s",s+1);64 for(int j=1;j<=m;++j)65 for(int k=0;k<4;++k){66 int x=(i+dx[k]-1+n)%n+1,y=(j+dy[k]-1+m)%m+1;67 (k==c[s[j]])?add(id[i][j],id[x][y]+n*m,1,0):add(id[i][j],id[x][y]+n*m,1,1);68 }69 }70 for(int i=1;i<=n*m;++i)71 add(S,i,1,0),add(i+n*m,T,1,0);72 zkw();73 printf("%d\n",ans);74 return 0;75 }

 

转载于:https://www.cnblogs.com/bztMinamoto/p/9581054.html

你可能感兴趣的文章