• Topcoder SRM570 900 CurvyonRails


    题意:给定一个网格,一些格子是障碍不用管,剩余的格子是城市,你可以修建铁路,铁路的形状可以是直的或者弯的,也就是说可以以这个点为节点连接它四联通的其中两个方块。要求用一个或多个环来覆盖所有城市。对于有些关键点,如果这里是直轨道,会付出1的代价,如果不能覆盖,输出-1,否则输出最小代价。

    这次该最小费用流了。x先考虑怎么判断有无解。很明显,既然是棋盘,想不染色不二分图都难。染成黑白后,对于黑点,S向其连2,黑点向周围的白点连1,白点向T连2,判断是否满流就好了。那么怎么计算代价呢?我们发现,如果要付出代价,那么一定是两个开口都给了同一列或者同一行,为了对此限制,我们拆点,分别管辖行和列。

    如果这个点是黑关键点,我们向行对应的分身连一个容量1,费用0的边,再连一个容量1,费用1的边,表示如果只用一条边,不会产生费用,否则产生两条边的费用。列的话同理。

    白关键点就不赘述了,其实也就是相较于反了一下。对于普通点,直接相对应的两个点分别连(2,0)就好了(因为没有限制),然后黑连向对应的白就好了。

    跑费用流,不满流无解,满流输出费用即可。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define INF 1e9
     4 #define N 5005
     5 #define id(i,j) ((i-1)*m+j)
     6 int n,m,TOT,S,T,P,head[N],d[N],a[N],p[N],cnt;
     7 bool vis[N];
     8 queue<int>q;
     9 char field[N][N];
    10 inline int read(){
    11     int x=0,f=1; char a=getchar();
    12     while(a<'0' || a>'9') {if(a=='-') f=-1; a=getchar();}
    13     while(a>='0' && a<='9') x=x*10+a-'0',a=getchar();
    14     return x*f;
    15 }
    16 struct edges{
    17     int fr,to,cap,flow,cost,next;
    18 }e[2*N];
    19 
    20 inline void insert(int u,int v,int f,int c){
    21     e[cnt]=(edges){u,v,f,0,c,head[u]};head[u]=cnt++;
    22     e[cnt]=(edges){v,u,0,0,-c,head[v]};head[v]=cnt++;
    23 }
    24 inline bool spfa(){
    25     memset(d,0x3f,sizeof(d));
    26     d[S]=0; a[S]=INF; q.push(S);
    27     while(!q.empty()){
    28         int x=q.front(); q.pop(); vis[x]=0;
    29         for(int i=head[x];i>=0;i=e[i].next)
    30             if(d[e[i].to]>d[x]+e[i].cost && e[i].flow<e[i].cap){
    31                 d[e[i].to]=d[x]+e[i].cost; p[e[i].to]=i;
    32                 a[e[i].to]=min(a[x],e[i].cap-e[i].flow);
    33                 if(!vis[e[i].to]) vis[e[i].to]=1,q.push(e[i].to);
    34             }
    35     }
    36     return d[T]<INF;
    37 }
    38 inline int mincf(){
    39     int u=T;
    40     while(u!=S){
    41         e[p[u]].flow+=a[T];
    42         e[p[u]^1].flow-=a[T];
    43         u=e[p[u]].fr;
    44     }
    45     TOT-=a[T];
    46     return a[T]*d[T];
    47 }
    48 
    49 int main(){
    50     n=read(); m=read();
    51     for(int i=1;i<=n;i++)
    52     scanf("%s",field[i]+1);
    53     S=0; T=3*n*m+1; P=n*m; TOT=0;
    54     memset(head,-1,sizeof(head));
    55     for(int i=1;i<=n;i++)
    56         for(int j=1;j<=m;j++){
    57                if(field[i][j]=='w') continue;    
    58             if((i+j)%2==0){
    59                 insert(S,id(i,j),2,0); TOT+=2;
    60                 if(field[i][j]!='C') insert(id(i,j),id(i,j)+2*P,2,0),insert(id(i,j),id(i,j)+P,2,0);
    61                 else {
    62                     insert(id(i,j),id(i,j)+P,1,1); insert(id(i,j),id(i,j)+P,1,0);
    63                     insert(id(i,j),id(i,j)+2*P,1,1); insert(id(i,j),id(i,j)+2*P,1,0);
    64                 }
    65                 if(j-1>0 && field[i][j-1]!='w') insert(id(i,j)+P,id(i,j-1)+P,1,0);
    66                 if(j+1<=m && field[i][j+1]!='w' ) insert(id(i,j)+P,id(i,j+1)+P,1,0);
    67                 if(i-1>0 && field[i-1][j]!='w') insert(id(i,j)+2*P,id(i-1,j)+2*P,1,0);
    68                 if(i+1<=n && field[i+1][j]!='w') insert(id(i,j)+2*P,id(i+1,j)+2*P,1,0);
    69             }else{
    70                 insert(id(i,j),T,2,0);
    71                 if(field[i][j]!='C') insert(id(i,j)+2*P,id(i,j),2,0),insert(id(i,j)+P,id(i,j),2,0);
    72                 else{
    73                     insert(id(i,j)+P,id(i,j),1,1); insert(id(i,j)+P,id(i,j),1,0);
    74                     insert(id(i,j)+2*P,id(i,j),1,1); insert(id(i,j)+2*P,id(i,j),1,0);
    75                 }
    76             }
    77         }
    78     int ans=0;
    79     while(spfa()) ans+=mincf();
    80     if(TOT) ans=-1;
    81     printf("%d
    ",ans);
    82 }
  • 相关阅读:
    c/c++基础 输入函数/流
    数据库的码/键
    sql plus笔记
    cmd delete oracle related
    CAN总线
    SAR ADC : 逐次逼近寄存器型(SAR)模数转换器(ADC)
    Cortex-M3寄存器等基础知识
    Cortex-M3知识点
    ARM指令和Thumb指令区别
    8051、ARM、AVR
  • 原文地址:https://www.cnblogs.com/enigma-aw/p/6237246.html
Copyright © 2020-2023  润新知