zoukankan      html  css  js  c++  java
  • [bzoj3171]循环格

    如果把这个矩阵看成一张图,题目相当于要求每一个点的入度和出度都是1(也就是有很多环),否则指向环的点就无法走回自己了
    将所有点拆成两个,S向原来的点流(1,0)的边,拆出来的点向T连(1,0)的边,然后每一个点指向初始方向上的点(1,0)的边,指向非初始方向上(1,1)的边,求最小费用最大流即可(也就是让其满足此条件)

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define N 1005
     4 struct ji{
     5     int nex,to,len,cost;
     6 }edge[N<<2];
     7 queue<int>q;
     8 int E,n,m,x,y,ans,dx[4]={-1,0,0,1},dy[4]={0,-1,1,0},head[N],vis[N],d[N],from[N];
     9 char c[4]={'U','L','R','D'},s[N];
    10 int id(int x,int y){
    11     return x*m+y+1;
    12 }
    13 void add(int x,int y,int z,int w){
    14     edge[E].nex=head[x];
    15     edge[E].to=y;
    16     edge[E].len=z;
    17     edge[E].cost=w;
    18     head[x]=E++;
    19     if (E&1)add(y,x,0,-w);
    20 }
    21 bool spfa(){
    22     memset(d,0x3f,sizeof(d));
    23     memset(vis,0,sizeof(vis));
    24     q.push(0);
    25     d[0]=0;
    26     while (!q.empty()){
    27         int k=q.front();
    28         q.pop();
    29         for(int i=head[k];i!=-1;i=edge[i].nex){
    30             int v=edge[i].to;
    31             if ((edge[i].len)&&(d[v]>d[k]+edge[i].cost)){
    32                 from[v]=i;
    33                 d[v]=d[k]+edge[i].cost;
    34                 if (!vis[v]){
    35                     vis[v]=1;
    36                     q.push(v);
    37                 }
    38             }
    39         }
    40         vis[k]=0;
    41     }
    42     return d[2*n*m+1]<0x3f3f3f3f;
    43 }
    44 int main(){
    45     scanf("%d%d",&n,&m);
    46     memset(head,-1,sizeof(head));
    47     for(int i=0;i<n;i++)
    48         for(int j=0;j<m;j++){
    49             add(0,id(i,j),1,0);
    50             add(id(i,j)+n*m,2*n*m+1,1,0);
    51         }
    52     for(int i=0;i<n;i++){
    53         scanf("%s",s);
    54         for(int j=0;j<m;j++)
    55             for(int k=0;k<4;k++){
    56                 x=(i+dx[k]+n)%n;
    57                 y=(j+dy[k]+m)%m;
    58                 add(id(i,j),id(x,y)+n*m,1,(c[k]!=s[j]));
    59             }
    60     }
    61     while (spfa()){
    62         ans+=d[2*n*m+1];
    63         for(int i=2*n*m+1;i;i=edge[from[i]^1].to){
    64             edge[from[i]].len--;
    65             edge[from[i]^1].len++;
    66         }
    67     }
    68     printf("%d",ans);
    69 }
    View Code
  • 相关阅读:
    Hbase 命令小结
    shell while内获取外部变量内容
    Idea的live template参数中的预定义功能
    Adobe Illustrator里使用fontawesome矢量图标
    五笔结构与识别码
    致第一次安装RIME的你
    sublime Text Pastry使用
    PHOTOSHOP CC 2015插件安装方法
    搭建自己的OpenWrt开发环境
    【OpenWRT】 Chaos Calmer 15.05 编译
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/11836017.html
Copyright © 2011-2022 走看看