zoukankan      html  css  js  c++  java
  • bzoj3171: [Tjoi2013]循环格(费用流)

    传送门

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

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

    那么我们考虑拆点

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

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

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

    那么最小费用就是答案了

     1 //minamoto
     2 #include<iostream>
     3 #include<cstdio>
     4 #include<cstring>
     5 #include<queue>
     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<int> 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
    ",ans);
    74     return 0;
    75 }
  • 相关阅读:
    jqGrid详解及高级应用(十四)
    ERP存储过程的调用和树形菜单的加载(四)
    IDisposable接口
    SQL调用系统存储过程整理
    Net作业调度-----Quartz.Net
    C#泛型(二)
    ERP通用存储过程封装(三)
    ERP PowerDesigner工具使用(二)
    ERP简介(一)
    jQuery.TreeView插件实现树状导航(十三)
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/9581054.html
Copyright © 2011-2022 走看看