bzoj4823: [Cqoi2017]老C的方块(最小割)
4823: [Cqoi2017]老C的方块
题目:传送门
题解:
毒瘤题ORZ....
太菜了看出来是最小割啥边都不会建...狂%大佬强强强
黑白染色?不!是四个色一起染,四层图跑最小割。。。
很惊奇的发现染完色之后只要是不喜欢的图形都一定可以由黄-->黑-->红-->绿 组成
那就很nice啦...兴高采烈的去敲代码...结果10^5*10^5???搞毛线...太弱了ORZ,又看了一波大佬的操作,用map存!
woc...不谈了不谈了...撸撸撸(分情况分到想屎...虽然不多)
注意一下...黑到红连边的时候是不可以连inf的...然而我傻逼逼的打了...改成min(w[黑],w[红])...
代码:
1 #include<cstdio> 2 #include<cstring> 3 #include<cstdlib> 4 #include<cmath> 5 #include<algorithm> 6 #include<map> 7 #define inf 999999999 8 #define qread(x) x=read() 9 using namespace std; 10 typedef long long LL; 11 inline LL read() 12 { 13 LL x=0,f=1;char ch; 14 while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();} 15 while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();} 16 return f*x; 17 } 18 struct node 19 { 20 int x,y,c,next,other; 21 }a[1110000];int len,last[410000]; 22 int n,m,T,st,ed; 23 void ins(int x,int y,int c) 24 { 25 int k1,k2; 26 k1=++len; 27 a[len].x=x;a[len].y=y;a[len].c=c; 28 a[len].next=last[x];last[x]=len; 29 30 k2=++len; 31 a[len].x=y;a[len].y=x;a[len].c=0; 32 a[len].next=last[y];last[y]=len; 33 34 a[k1].other=k2; 35 a[k2].other=k1; 36 } 37 int head,tail; 38 int list[410000],h[410000]; 39 bool bt_h() 40 { 41 memset(h,0,sizeof(h));h[st]=1; 42 list[1]=st;head=1;tail=2; 43 while(head!=tail) 44 { 45 int x=list[head]; 46 for(int k=last[x];k;k=a[k].next) 47 { 48 int y=a[k].y; 49 if(!h[y] && a[k].c) 50 { 51 h[y]=h[x]+1; 52 list[tail++]=y; 53 } 54 } 55 head++; 56 } 57 if(h[ed])return true; 58 return false; 59 } 60 int find_flow(int x,int flow) 61 { 62 int s=0,t; 63 if(x==ed)return flow; 64 for(int k=last[x];k;k=a[k].next) 65 { 66 int y=a[k].y; 67 if(h[y]==h[x]+1 && a[k].c && s<flow) 68 { 69 s+=t=find_flow(y,min(a[k].c,flow-s)); 70 a[k].c-=t;a[a[k].other].c+=t; 71 } 72 } 73 if(!s)h[x]=0; 74 return s; 75 } 76 int x[110000],y[110000],w[110000];//第x列,第y行,金币数 77 map<pair<int,int>,int>id; 78 int main() 79 { 80 len=0;memset(last,0,sizeof(last)); 81 memset(w,0,sizeof(w)); 82 qread(n);qread(m);qread(T);st=T+1;ed=st+1; 83 for(int i=1;i<=T;i++){qread(x[i]);qread(y[i]);qread(w[i]);id[make_pair(x[i],y[i])]=i;} 84 //黄-->黑-->红-->绿 85 for(int i=1;i<=T;i++) 86 { 87 if(x[i]%4==0)//黑或黄 88 { 89 if(y[i]%2==1)ins(st,i,w[i]);//黄 90 else//黑 91 { 92 if(id[make_pair(x[i]+1,y[i])])ins(id[make_pair(x[i]+1,y[i])],i,inf); 93 if(id[make_pair(x[i],y[i]+1)])ins(id[make_pair(x[i],y[i]+1)],i,inf); 94 if(id[make_pair(x[i],y[i]-1)])ins(id[make_pair(x[i],y[i]-1)],i,inf); 95 } 96 } 97 if(x[i]%4==1)//黑或黄 98 { 99 if(y[i]%2==0)ins(st,i,w[i]);//黄 100 else//黑 101 { 102 //黑-->黄 103 if(id[make_pair(x[i],y[i]-1)])ins(id[make_pair(x[i],y[i]-1)],i,inf); 104 if(id[make_pair(x[i],y[i]+1)])ins(id[make_pair(x[i],y[i]+1)],i,inf); 105 if(id[make_pair(x[i]-1,y[i])])ins(id[make_pair(x[i]-1,y[i])],i,inf); 106 107 //黑-->红(计算w) 108 if(id[make_pair(x[i]+1,y[i])]) 109 ins(i,id[make_pair(x[i]+1,y[i])],min(w[i],w[id[make_pair(x[i]+1,y[i])]])); 110 } 111 } 112 if(x[i]%4==2)//红或绿 113 { 114 if(y[i]%2==1)//红 115 { 116 if(id[make_pair(x[i],y[i]-1)])ins(i,id[make_pair(x[i],y[i]-1)],inf); 117 if(id[make_pair(x[i],y[i]+1)])ins(i,id[make_pair(x[i],y[i]+1)],inf); 118 if(id[make_pair(x[i]+1,y[i])])ins(i,id[make_pair(x[i]+1,y[i])],inf); 119 } 120 else ins(i,ed,w[i]);//绿 121 } 122 if(x[i]%4==3)//红或绿 123 { 124 if(y[i]%2==0)//红 125 { 126 //红-->绿 127 if(id[make_pair(x[i],y[i]-1)])ins(i,id[make_pair(x[i],y[i]-1)],inf); 128 if(id[make_pair(x[i],y[i]+1)])ins(i,id[make_pair(x[i],y[i]+1)],inf); 129 if(id[make_pair(x[i]-1,y[i])])ins(i,id[make_pair(x[i]-1,y[i])],inf); 130 131 //黑-->红 132 if(id[make_pair(x[i]+1,y[i])]) 133 ins(id[make_pair(x[i]+1,y[i])],i,min(w[i],w[id[make_pair(x[i]+1,y[i])]])); 134 } 135 else ins(i,ed,w[i]);//绿 136 } 137 } 138 int ans=0; 139 while(bt_h())ans+=find_flow(st,inf); 140 printf("%d\n",ans); 141 return 0; 142 }