• LOJ 2321 清华集训2017 无限之环 拆点+最小费用最大流


    题面:中文题面,这里不占用篇幅

     

    分析:

      看到题面,我就想弃疗……

      但是作为任务题单,还是抄了题解……

      大概就是将每个格子拆点,拆成五个点,上下左右的触点和一个负责连源汇点的点(以下简称本点)。

      这个这个本点要根据初始形态向相应的触点连接费用为0容量为1的边,再由旋转规则,使初始触点向相应的触点连接费用为旋转次数的边,然后相邻的格子触点相连?

      反正很乱就是了。如果再写一遍,我应该不会写罢……

    代码:(这份代码在Luogu上不开O2会TLE十八组数据……开了才能过,在loj是可过的)

     1 #include<bits/stdc++.h>
     2 #define up(u) u+tn*sm
     3 #define ri(u) u+((tn+1)&3)*sm
     4 #define dn(u) u+((tn+2)&3)*sm
     5 #define le(u) u+((tn+3)&3)*sm
     6 #define md(u) u+(sm<<2)
     7 using namespace std;queue<int>q;
     8 const int N=20005,M=200005,inf=0x3f3f3f3f;
     9 struct node{int y,z,f,nxt;}e[M];
    10 int mf=0,f[N],lst[N],ans=0;bool vis[N];
    11 int sm,c=1,S=0,T,h[N],d[N],pre[N],n,m,k;
    12 void add(int x,int y,int f,int z,int tp){
    13     if(tp) swap(x,y);
    14     e[++c]=(node){y,z,f,h[x]};h[x]=c;
    15     e[++c]=(node){x,-z,0,h[y]};h[y]=c;
    16 } bool spfa(){
    17     for(int i=S;i<=T;i++) pre[i]=-1,
    18     f[i]=inf,lst[i]=vis[i]=0,d[i]=inf;
    19     q.push(S);d[S]=0;pre[S]=0;
    20     while(q.size()){
    21         int x=q.front();q.pop();vis[x]=0;
    22         for(int i=h[x],y;i;i=e[i].nxt)
    23         if(d[y=e[i].y]>d[x]+e[i].z&&e[i].f){
    24             d[y]=d[x]+e[i].z;pre[y]=x;lst[y]=i;
    25             f[y]=min(f[x],e[i].f);
    26             if(!vis[y]) vis[y]=1,q.push(y);
    27         }
    28     } return (pre[T]!=-1);
    29 } void solve(){
    30     while(spfa()){
    31         ans+=d[T]*f[T];int x=T;mf+=f[T];
    32         while(x) e[lst[x]].f-=f[T],
    33         e[lst[x]^1].f+=f[T],x=pre[x];
    34     } return ;
    35 } int main(){
    36     k=1;int t,sp,tn,tf=0,mc=0;
    37     scanf("%d%d",&n,&m);sm=n*m;T=sm*5+1;
    38     for(int i=0;i<n;i++)
    39     for(int j=0;j<m;j++,k++){
    40         tn=0;t=(i+j)&1;
    41         if(t) add(S,md(k),inf,0,0);
    42         else add(md(k),T,inf,0,0);
    43         if(i) add(dn(k-m),up(k),1,0,t);
    44         if(j) add(ri(k-1),le(k),1,0,t);
    45         scanf("%d",&sp);
    46         if(sp&1) add(up(k),md(k),1,0,t),tf++;
    47         if(sp&2) add(ri(k),md(k),1,0,t),tf++;
    48         if(sp&4) add(dn(k),md(k),1,0,t),tf++;
    49         if(sp&8) add(le(k),md(k),1,0,t),tf++;
    50         switch(sp){
    51             case 8:tn++;
    52             case 4:tn++;
    53             case 2:tn++;
    54             case 1:
    55                 add(ri(k),up(k),1,1,t);
    56                 add(dn(k),up(k),1,2,t);
    57                 add(le(k),up(k),1,1,t);break;
    58             case 9:tn++;
    59             case 12:tn++;
    60             case 6:tn++;
    61             case 3:
    62                 add(dn(k),up(k),1,1,t);
    63                 add(le(k),ri(k),1,1,t);break;
    64             case 13:tn++;
    65             case 14:tn++;
    66             case 7:tn++;
    67             case 11:
    68                 add(dn(k),le(k),1,1,t);
    69                 add(dn(k),up(k),1,2,t);
    70                 add(dn(k),ri(k),1,1,t);break;
    71         } 
    72     } solve();
    73     printf("%d",tf==mf<<1?ans:-1);return 0;
    74 }
    费用流


      

  • 相关阅读:
    How to resolve mysql problem when you get code 2003(10061) and 1130
    Windows connect to mysql failed: can't get hostname for your address
    Python基础教程总结(二)
    Python基础教程总结(一)
    Begin to study Deep Learning
    再坚持一点点
    技术到管理的必经之路(2)
    技术到管理的必经之路(1)
    c#进阶(7)—— 异步编程基础(async 和 await 关键字)
    c#进阶(6)—— 网络通信基础知识
  • 原文地址:https://www.cnblogs.com/Alan-Luo/p/10242587.html
Copyright © 2020-2023  润新知