题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=3171

题意:

思路:若能构成循环,则每个格子的入度出度
均为1。因此将每个点拆成两个点x1,x2,分别作为出点和入点。出点向周围四个点的入点连边,流1,费用视该格子的字母而定。该格子的字母正好是这个方
向则费用为0否则为1。原点S向每个出点连边,流量1费用0;每个入点向汇点连边,流量1费用0。求最小费用最大流即可。

struct node
{
    int u,v,next,cost,cap;
};

node edges[N];
int head[N],e;

void add(int u,int v,int cap,int cost)
{
    edges[e].u=u;
    edges[e].v=v;
    edges[e].cap=cap;
    edges[e].cost=cost;
    edges[e].next=head[u];
    head[u]=e++;
}

void Add(int u,int v,int cap,int cost)
{
    add(u,v,cap,cost);
    add(v,u,0,-cost);
}

int pre[N],F[N],C[N],visit[N];

int SPFA(int s,int t,int n)
{
    int i;
    for(i=0;i<=n;i++) F[i]=0,C[i]=INF,visit[i]=0;
    queue<int> Q;
    Q.push(s); F[s]=INF; C[s]=0;
    int u,v,cost,cap;
    while(!Q.empty())
    {
        u=Q.front();
        Q.pop();

        visit[u]=0;
        for(i=head[u];i!=-1;i=edges[i].next)
        {
            if(edges[i].cap>0)
            {
                v=edges[i].v;
                cost=edges[i].cost;
                cap=edges[i].cap;
                if(C[v]>C[u]+cost)
                {
                    C[v]=C[u]+cost;
                    F[v]=min(F[u],cap);
                    pre[v]=i;
                    if(!visit[v]) visit[v]=1,Q.push(v);
                }
            }
        }
    }
    return F[t];
}

int MCMF(int s,int t,int n)
{
    int ans=0,i,x,temp;
    while(temp=SPFA(s,t,n))
    {
        for(i=t;i!=s;i=edges[pre[i]].u)
        {
            x=pre[i];
            ans+=edges[x].cost*temp;
            edges[x].cap-=temp;
            edges[x^1].cap+=temp;
        }
    }
    return ans;
}

int a[20][20][2],s,t,n,m;
char S[20][20];

int main()
{
    RD(n,m);
    int i,j,k=0;
    FOR1(i,n) FOR1(j,m)
    {
        a[i][j][0]=++k;
        a[i][j][1]=++k;
    }
    s=0; t=++k;
    FOR1(i,n) RD(S[i]+1);
    int L,R,U,D;
    clr(head,-1);
    FOR1(i,n) FOR1(j,m)
    {
        if(S[i][j]=='U') U=0;
        else U=1;
        if(S[i][j]=='D') D=0;
        else D=1;
        if(S[i][j]=='L') L=0;
        else L=1;
        if(S[i][j]=='R') R=0;
        else R=1;
        if(i==1) Add(a[i][j][0],a[n][j][1],1,U);
        else Add(a[i][j][0],a[i-1][j][1],1,U);

        if(i==n) Add(a[i][j][0],a[1][j][1],1,D);
        else Add(a[i][j][0],a[i+1][j][1],1,D);

        if(j==1) Add(a[i][j][0],a[i][m][1],1,L);
        else Add(a[i][j][0],a[i][j-1][1],1,L);

        if(j==m) Add(a[i][j][0],a[i][1][1],1,R);
        else Add(a[i][j][0],a[i][j+1][1],1,R);

        Add(s,a[i][j][0],1,0);
        Add(a[i][j][1],t,1,0);
    }
    PR(MCMF(s,t,t));
}

BZOJ 3171 循环格(费用流)的更多相关文章

  1. BZOJ 3171 循环格(费用流)

    题意 一个循环格就是一个矩阵,其中所有元素为箭头,指向相邻四个格子.每个元素有一个坐标(行,列),其中左上角元素坐标为(0,0).给定一个起始位置(r,c),你可以沿着箭头防线在格子间行走.即如果(r ...

  2. Bzoj 3171: [Tjoi2013]循环格 费用流

    3171: [Tjoi2013]循环格 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 741  Solved: 463[Submit][Status][ ...

  3. BZOJ 3171 循环格 最小费用流

    题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=3171 题目大意: 一个循环格就是一个矩阵,其中所有元素为箭头,指向相邻四个格子.每个元 ...

  4. [TJOI2013]循环格 费用流 BZOJ3171

    题目背景 一个循环格就是一个矩阵,其中所有元素为箭头,指向相邻四个格子.每个元素有一个坐标(行,列),其中左上角元素坐标为(0,0).给定一个起始位(r,c),你可以沿着箭头方向在格子间行走.即:如果 ...

  5. [bzoj 1449] 球队收益(费用流)

    [bzoj 1449] 球队收益(费用流) Description Input Output 一个整数表示联盟里所有球队收益之和的最小值. Sample Input 3 3 1 0 2 1 1 1 1 ...

  6. BZOJ.2597.[WC2007]剪刀石头布(费用流zkw)

    BZOJ 洛谷 \(Description\) 给定一张部分边方向已确定的竞赛图.你需要给剩下的边确定方向,使得图中的三元环数量最多. \(n\leq100\). \(Solution\) 这种选择之 ...

  7. bzoj 1070: [SCOI2007]修车 费用流

    1070: [SCOI2007]修车 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 2785  Solved: 1110[Submit][Status] ...

  8. BZOJ 1070 修车 【费用流】

    Description 同一时刻有N位车主带着他们的爱车来到了汽车维修中心.维修中心共有M位技术人员,不同的技术人员对不同 的车进行维修所用的时间是不同的.现在需要安排这M位技术人员所维修的车及顺序, ...

  9. BZOJ 1930 吃豆豆(费用流)

    首先这题的两条线不相交的限制可以去掉,因为如果相交的话把点换一换是不影响最终结果的. 剩下的费用流建图是显然的,把点拆为两个,建立超级源点s和源点ss汇点t,连边(s,ss,2,0). 对于每个点,连 ...

随机推荐

  1. WM_SIZE

    procedure WMSize (var Message: TWMSize); message WM_SIZE; 参数说明 wParam: Specifies the type of resizin ...

  2. ==,equal,hasCode(),identifyHasCode()浅析

    在java中如果我们要比较两个对象之间的关系的话有可能会用到下面的几种方法:==,equal,hasCode(),identifyHasCode(). ==用来比较对象本身是不是相同的. public ...

  3. android 学习随笔二十八(应用小知识点小结 )

    去掉标题栏的方法 第一种:也一般入门的时候经常使用的一种方法requestWindowFeature(Window.FEATURE_NO_TITLE);//去掉标题栏注意这句一定要写在setConte ...

  4. jenkins相关

    1. jenkins maven tomcat做持续集成的时候几个关键配置:http://my.oschina.net/congqian/blog/112782?fromerr=PmIDbLs5 2. ...

  5. 用grunt搭建自动化的web前端开发环境实战教程(详细步骤)

    用grunt搭建自动化的web前端开发环境实战教程(详细步骤) jQuery在使用grunt,bootstrap在使用grunt,百度UEditor在使用grunt,你没有理由不学.不用!前端自动化, ...

  6. Backup: Date and Time in Perl6

    时间 Date #Operators ==, <, <= , >, >=, !=, eq, lt, le # Methods $date = Date.new(YEAR, MO ...

  7. flex mx组件和s组件的字体兼容性不一致

    <?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="ht ...

  8. 在centos6.5-64bit上安装wxHexEditor,以查看编译二进制文件

    目前在做一个存储,磁盘里面的数据老是出现很诡异的地方,某个通道的录像播放到一半的时候,切换到另外一个通道的视频上去了,一直不知道怎么下手,想着用十六进制编辑器查看磁盘数据. sudo yum inst ...

  9. C++中this指针的用法详解

    转自 http://blog.chinaunix.net/uid-21411227-id-1826942.html 1. this指针的用处: 一个对象的this指针并不是对象本身的一部分,不会影响s ...

  10. snackbar初体验

    底部弹出的部分就是snackbar的,右侧可添加一个action响应点击事件,遗憾的时貌似只能添加一个 这是华为mate8上面运行出来的效果,颜色之类的都是默认.不同的android版本样式稍有差异 ...