想通过这题来学最大点权独立集,不过貌似可以直接做?(结果没学成= =)
黑白染色并分别连ST,容量为权值,然后相邻格子连边,容量INF
看到中文题目激动了忘了有多组数据(雾
1 //#include<bits/stdc++.h> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<iostream> 6 #include<queue> 7 #define inc(i,l,r) for(int i=l;i<=r;i++) 8 #define dec(i,l,r) for(int i=l;i>=r;i--) 9 #define link(x) for(edge *j=h[x];j;j=j->next) 10 #define mem(a) memset(a,0,sizeof(a)) 11 #define inf 1e9 12 #define ll long long 13 #define succ(x) (1<<x) 14 #define NM 1000 15 #define nm 10000 16 using namespace std; 17 int read(){ 18 int x=0,f=1;char ch=getchar(); 19 while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} 20 while(isdigit(ch))x=x*10+ch-'0',ch=getchar(); 21 return x*f; 22 } 23 struct edge{ 24 int t,v; 25 edge *next,*rev; 26 }e[nm],*h[NM],*p=e; 27 void _add(int x,int y,int v){ 28 p->t=y;p->v=v;p->next=h[x];h[x]=p;p++; 29 } 30 void add(int x,int y,int v){ 31 _add(x,y,v);_add(y,x,0); 32 h[x]->rev=h[y];h[y]->rev=h[x]; 33 } 34 int n,m,s,_t,_x,d[NM],b[30][30],tot; 35 const int dir[4][2]={0,1,1,0,0,-1,-1,0}; 36 queue<int >q; 37 bool check(int x){ 38 return x>=1&&x<=n; 39 } 40 int bfs(){ 41 mem(d); 42 d[0]++;q.push(0); 43 while(!q.empty()){ 44 int t=q.front();q.pop(); 45 link(t) 46 if(j->v&&!d[j->t]) 47 d[j->t]=d[t]+1,q.push(j->t); 48 } 49 return d[n]; 50 } 51 int dfs(int x,int k){ 52 int _a; 53 if(x==n)return k; 54 link(x) 55 if(j->v&&d[j->t]==d[x]+1&&(_a=dfs(j->t,min(j->v,k)))){ 56 j->v-=_a;j->rev->v+=_a;return _a; 57 } 58 return 0; 59 } 60 int main(){ 61 // freopen("data.in","r",stdin); 62 while(scanf("%d",&n)!=EOF){ 63 tot=s=0;mem(b);p=e;mem(h); 64 inc(i,1,n) 65 inc(j,1,n) 66 b[i][j]=++tot; 67 inc(i,1,n) 68 inc(j,1,n){ 69 _x=read();s+=_x; 70 if((i+j)%2)add(b[i][j],tot+1,_x); 71 else{ 72 add(0,b[i][j],_x); 73 inc(k,0,3) 74 if(check(i+dir[k][0])&&check(j+dir[k][1])) 75 add(b[i][j],b[i+dir[k][0]][j+dir[k][1]],inf); 76 } 77 } 78 n=tot+1; 79 while(bfs()) 80 if(_t=dfs(0,inf))s-=_t; 81 printf("%d\n",s); 82 } 83 return 0; 84 }