zoukankan      html  css  js  c++  java
  • BZOJ 4213 贪吃蛇 上下界费用流 网络流

    https://darkbzoj.cf/problem/4213

    https://www.cnblogs.com/DaD3zZ-Beyonder/p/5733326.html 题目描述 dbzoj又崩了存个代码

    一条对答案有贡献的蛇一定有两个点在边界上且这两个点都只连了一条边,这条蛇上的其他点一定都连了两条边。

    把格子按照如国际象棋棋盘的样式黑白填充,那么一条蛇是一条链(或者环),链上的点黑白交错。

    对每个白点匹配两个相邻的黑点(黑白填充是为了方便建图(类似于二分图匹配)),只能匹配一个相邻点的点的数量的最小值/2就是最少的有贡献的蛇的数量。

    所以建图为

    s -> 白 流量2 费用0 上下界2

    黑 -> t 流量2 费用0 上下界2

    白 -> 相邻黑 流量1费用0 

    边缘白 -> t 流量1费用1

    s -> 边缘黑 流量1费用1

    改造成上下界的就可以了。同这道题→BZOJ2055 80人环游世界

     
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cmath>
     6 #include<queue>
     7 using namespace std;
     8 #define LL long long
     9 const int maxn=60100;
    10 int n=0,m=0,mx=0,ss=0,tt=0,S=0,T=0,z;
    11 char ch[20][20];
    12 struct nod{
    13     int y,v,co,nex;
    14 }e[maxn];
    15 int head[400]={},tot=1;
    16 int d[400]={},id[20][20]={},ans=0;
    17 void init(int x,int y,int v,int co){
    18     e[++tot].y=y;e[tot].v=v;e[tot].co=co;e[tot].nex=head[x];head[x]=tot;
    19     e[++tot].y=x;e[tot].v=0;e[tot].co=-co;e[tot].nex=head[y];head[y]=tot;
    20 }
    21 int dis[400];bool vis[400]={};
    22 queue<int>q;
    23 bool SPFA(){
    24     memset(dis,31,sizeof(dis));
    25     memset(vis,0,sizeof(vis));
    26     int tn=dis[1];
    27     q.push(S);dis[S]=0;vis[S]=1;
    28     while(!q.empty()){
    29         int x=q.front(),y;q.pop();vis[x]=0;
    30         for(int i=head[x];i;i=e[i].nex){
    31             y=e[i].y;
    32             if(e[i].v>0&&dis[y]>dis[x]+e[i].co){
    33                 dis[y]=dis[x]+e[i].co;
    34                 if(!vis[y]){vis[y]=1;q.push(y);}
    35             }
    36         }
    37     }
    38     return dis[T]!=tn;
    39 }
    40 int dfs(int x,int flo){
    41     if(x==T){
    42         ans+=dis[x]*flo;return flo;
    43     }vis[x]=1;
    44     int liu=0,tv,y;
    45     for(int i=head[x];i;i=e[i].nex){
    46         y=e[i].y;
    47         if(vis[y]||dis[y]!=dis[x]+e[i].co||e[i].v<=0)continue;
    48         tv=dfs(y,min(flo-liu,e[i].v));
    49         liu+=tv;e[i].v-=tv;e[i^1].v+=tv;
    50         if(liu==flo)break;
    51     }
    52     return liu;
    53 }
    54 bool Check(int x,int y){if(x>=1&&x<=n&&y>=1&&y<=m&&ch[x][y]!='#')return 1;return 0;}
    55 void Buildedge(){
    56     for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) id[i][j]=(i-1)*m+j;
    57     for(int i=1;i<=n;i++){
    58         for(int j=1;j<=m;j++){
    59             if(ch[i][j]=='#')continue;
    60             if((i+j)&1){
    61                 d[ss]-=2;d[id[i][j]]+=2;
    62                 if(Check(i-1,j))init(id[i][j],id[i-1][j],1,0);
    63                 if(Check(i,j-1))init(id[i][j],id[i][j-1],1,0);
    64                 if(Check(i+1,j))init(id[i][j],id[i+1][j],1,0);
    65                 if(Check(i,j+1))init(id[i][j],id[i][j+1],1,0);
    66             }
    67             else {d[tt]+=2;d[id[i][j]]-=2;}        
    68         }
    69     }
    70     for(int i=1;i<=tt;i++){
    71         if(d[i]>0)init(S,i,d[i],0);
    72         if(d[i]<0) init(i,T,-d[i],0);
    73     }
    74     for(int i=1;i<=n;i++){
    75         for(int j=1;j<=m;j++){
    76             if(i==1||j==1||i==n||j==m){
    77                 if(ch[i][j]=='#')continue;
    78                 if((i+j)&1)init(id[i][j],tt,1,1);
    79                 else init(ss,id[i][j],1,1);
    80             }
    81         }
    82     }
    83     init(tt,ss,mx,0);
    84 }
    85 int main(){
    86     //freopen("a.in","r",stdin);
    87     n=1;
    88     while(~scanf("%s",ch[n]+1))++n; 
    89     n--;
    90     for(int i=1;;++i){m=i-1;if(ch[1][i]!='.'&&ch[1][i]!='#')break;}
    91     mx=n*m;ss=mx+1;tt=ss+1;S=tt+1;T=S+1;
    92     Buildedge();
    93     while(SPFA()){memset(vis,0,sizeof(vis));dfs(S,mx);}
    94     int f=1;
    95     for(int i=head[S];i;i=e[i].nex)if(e[i].v)f=0;
    96     if(f)printf("%d
    ",ans/2);
    97     else printf("-1
    ");
    98     return 0;
    99 }
    View Code

  • 相关阅读:
    Head First Servlets & JSP 学习笔记 第七章 —— 作为JSP
    Head First Servlets & JSP 学习笔记 第六章 —— 会话状态
    八大基本排序--基数排序
    Stack类常用api
    3.从尾到头打印链表
    八大基本排序--归并排序
    八大基本排序--选择排序
    八大基本排序--希尔排序
    八大基本排序--插入排序
    八大基本排序--冒泡排序
  • 原文地址:https://www.cnblogs.com/137shoebills/p/8983736.html
Copyright © 2011-2022 走看看