1. 程式人生 > >bzoj 4823 [Cqoi2017]老C的方塊——網絡流

bzoj 4823 [Cqoi2017]老C的方塊——網絡流

http namespace 很多 pre amp .com use 是把 pan

題目:https://www.lydsy.com/JudgeOnline/problem.php?id=4823

一個不合法方案其實就是藍線的兩邊格子一定選、剩下兩部分四相鄰格子裏各選一個。

所以這個圖是一個四分圖。記藍線左邊格子是1,右邊是2,與 1 四相鄰的是3,與 2 四相鄰的是4;這個部分右邊就是藍線左邊是2、右邊是1,這樣。

有一些“4個格子不能同時選”的限制,考慮怎麽在圖中表示。

需要做到的是4個格子裏割掉一個就能讓這條路徑廢掉,那麽應該是把有聯系的4個點連成一條鏈。因為是4分圖,所以能做到。

一個格子可能在很多路徑裏,如果在路徑的邊上放權值,不能表示割掉這個格子可以使很多路徑都廢掉。所以把格子拆成兩個點,自己向自己連的邊上放權值即可。

map 是一個有序結構,所以結構體的話要定義小於號。如果只定義了 x<b.x ,那麽在 x==b.x 的時候 map 會認為這是同一個點!即使它們的 y 不同。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
using namespace std;
const int N=2e5+5,M=2e6+5,INF=1e9+5;
int n,r,c,t,x[N],y[N],w[N];
int hd[N],xnt=1,cur[N],to[M],nxt[M],cap[M];
int dfn[N],q[N],he,tl; struct Node{ int x,y; Node(int a=0,int b=0):x(a),y(b) {} bool operator< (const Node &b)const {return x==b.x?y<b.y:x<b.x;}//////x<b.x will rec x==b.x as the same point }; map<Node,int> mp; int Mn(int a,int b){return a<b?a:b;} int rdn() { int
ret=0;bool fx=1;char ch=getchar(); while(ch>9||ch<0){if(ch==-)fx=0;ch=getchar();} while(ch>=0&&ch<=9)ret=ret*10+ch-0,ch=getchar(); return fx?ret:-ret; } void add(int x,int y,int z) { to[++xnt]=y;nxt[xnt]=hd[x];hd[x]=xnt;cap[xnt]=z; to[++xnt]=x;nxt[xnt]=hd[y];hd[y]=xnt;cap[xnt]=0; } bool bfs() { memset(dfn,0,sizeof dfn);dfn[0]=1; q[he=tl=1]=0; while(he<=tl) { int k=q[he++]; for(int i=hd[k],v;i;i=nxt[i]) if(cap[i]&&!dfn[v=to[i]]) dfn[v]=dfn[k]+1,q[++tl]=v; } return dfn[t]; } int dinic(int cr,int flow) { if(cr==t)return flow; int use=0; for(int& i=cur[cr],v;i;i=nxt[i]) if(cap[i]&&dfn[v=to[i]]==dfn[cr]+1) { int tmp=dinic(v,Mn(flow-use,cap[i])); if(!tmp)dfn[v]=0; use+=tmp;cap[i]-=tmp;cap[i^1]+=tmp; if(use==flow)return use; } return use; } int main() { c=rdn();r=rdn();n=rdn(); for(int i=1;i<=n;i++) { y[i]=rdn();x[i]=rdn();w[i]=rdn();//y[] then x[] mp[Node(x[i],y[i])]=i; } t=(n<<1)+1; Node o; for(int i=1;i<=n;i++) { add(i,i+n,w[i]); int u=(x[i]&1),v=(y[i]&3); if((u&&!v)||(!u&&v==1))add(0,i,INF);//3 else if((u&&v==3)||(!u&&v==2))add(i+n,t,INF);//4 else if((u&&v==1)||(!u&&!v))//1 { if(mp.count(o=Node(x[i]-1,y[i])))//3->1 add(mp[o]+n,i,INF); if(mp.count(o=Node(x[i]+1,y[i]))) add(mp[o]+n,i,INF); if(mp.count(o=Node(x[i],y[i]+1)))//1>2 or 3>1 u?add(i+n,mp[o],INF):add(mp[o]+n,i,INF); if(mp.count(o=Node(x[i],y[i]-1))) u?add(mp[o]+n,i,INF):add(i+n,mp[o],INF); } else//2 { if(mp.count(o=Node(x[i]-1,y[i]))) add(i+n,mp[o],INF); if(mp.count(o=Node(x[i]+1,y[i]))) add(i+n,mp[o],INF); if(mp.count(o=Node(x[i],u?y[i]+1:y[i]-1))) add(i+n,mp[o],INF); } } int ans=0; while(bfs())memcpy(cur,hd,sizeof hd),ans+=dinic(0,INF); printf("%d\n",ans); return 0; }

bzoj 4823 [Cqoi2017]老C的方塊——網絡流