解题:CQOI 2017 老C的方块

题面

看起来很像网络流的二分图套路题,然后我们大力观察(题目定义的相邻我用引号括起来,应该能看懂)

发现“相邻”的一对方格如果各自连着一个一个方格就gg了,于是对于所有这些“相邻”的方格,我们有两种选择

①移除一对“相邻”的方格中的一个

②把一对“相邻”的方格中的一个的所有相邻方格都移除

还可以发现二分图染色后一对“相邻”方格相邻的方格是一边白一边黑的

那么对于一对“相邻”的点连流量为点权最小值的边,黑白点分开向源汇点连流量等于点权的边,最后“相邻”点和和它们相邻的点用流量为正无穷的边连起来,然后图就建好了

 1 #include<map>
 2 #include<cmath>
 3 #include<cstdio>
 4 #include<cstring>
 5 #include<algorithm>
 6 using namespace std;
 7 const int N=100005,M=400005,inf=1e9;
 8 const int mov[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
 9 int p[N],pp[N],noww[2*M],goal[2*M],flow[2*M];
10 int dep[N],que[N],px[N],py[N],col[N],val[N];
11 int n,c,r,s,t,f,b,t1,t2,t3,cnt,tot,ans;
12 map<pair<int,int>,int> mmp;
13 void link(int f,int t,int v)
14 {
15     noww[++cnt]=p[f],p[f]=cnt;
16     goal[cnt]=t,flow[cnt]=v;
17     noww[++cnt]=p[t],p[t]=cnt;
18     goal[cnt]=f,flow[cnt]=0;
19 }
20 bool Layering(int st,int ed)
21 {
22     for(int i=1;i<=t;i++) pp[i]=p[i];
23     memset(dep,-1,sizeof dep);
24     dep[st]=0,que[f=b=0]=st;
25     while(f<=b)
26     {
27         int tn=que[f++];
28         for(int i=pp[tn];i;i=noww[i])
29             if(dep[goal[i]]==-1&&flow[i])
30                 dep[goal[i]]=dep[tn]+1,que[++b]=goal[i];
31     }
32     return ~dep[ed];
33 }
34 int Augmenting(int nd,int ed,int mn)
35 {
36     if(nd==ed||!mn) return mn;
37     int tmp=0,tep=0;
38     for(int i=pp[nd];i;i=noww[i])
39     {
40         pp[nd]=i;
41         if(dep[goal[i]]==dep[nd]+1)
42             if(tep=Augmenting(goal[i],ed,min(mn,flow[i])))
43             {
44                 flow[i]-=tep,mn-=tep;
45                 flow[i^1]+=tep,tmp+=tep;
46                 if(!mn) break;
47             }
48     }
49     return tmp;
50 }
51 void Dinic_Maxflow(int st,int ed)
52 {
53     while(Layering(st,ed))
54         ans+=Augmenting(st,ed,inf);
55 }
56 int main ()
57 {
58     scanf("%d%d%d",&c,&r,&n),cnt=1;
59     for(int i=1;i<=n;i++)
60     {
61         scanf("%d%d%d",&px[i],&py[i],&val[i]);
62         mmp[make_pair(px[i],py[i])]=++tot;
63     }
64     s=++tot,t=++tot;
65     for(int i=1;i<=n;i++)
66     {
67         int f=px[i]%4,g=py[i]%2;
68         if(!f) col[i]=g?3:1;
69         else if(f==1) col[i]=g?1:3;
70         else if(f==2) col[i]=g?2:4;
71         else if(f==3) col[i]=g?4:2;
72     }
73     for(int i=1;i<=n;i++)
74         if(col[i]==1) 
75             for(int j=0;j<4;j++)
76             {
77                 int tx=px[i]+mov[j][0],ty=py[i]+mov[j][1],num=mmp[make_pair(tx,ty)];
78                 if(num)    (col[num]==2)?link(i,num,min(val[i],val[num])):link(num,i,inf);
79             }
80         else if(col[i]==2)
81             for(int j=0;j<4;j++)
82             {
83                 int tx=px[i]+mov[j][0],ty=py[i]+mov[j][1],num=mmp[make_pair(tx,ty)];
84                 if(num&&col[num]!=1) link(i,num,inf);
85             }
86         else if(col[i]==3) link(s,i,val[i]);
87         else if(col[i]==4) link(i,t,val[i]);
88     Dinic_Maxflow(s,t),printf("%d",ans);
89     return 0;
90 }
View Code

猜你喜欢

转载自www.cnblogs.com/ydnhaha/p/10181385.html