HDU 1569 方格取数(2) << 最大点权独立集
题意
升级版的方格取数
思路
图中选一个点就不能选四周的点,转化为二分图,求最大点权独立集。要求最大点权独立集,即是求最小点权覆盖,求点权和减去最小割,即是求最小割,即是求最大流,关于建图,每个点向周围四个点建边即可,证明与说明略。
代码
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=1e4+7; 4 const int INF=0x3f3f3f3f; 5 struct Edge{ 6 int from,to,cap,flow; 7 }; 8 struct DINIC{ 9 int n,m,s,t; 10 vector<Edge> edges; 11 vector<int> G[maxn]; 12 bool vis[maxn]; 13 int d[maxn]; 14 int cur[maxn]; 15 16 void AddEdge(int from,int to,int cap,int c=0)//有向图c为0 17 { 18 edges.push_back(Edge {from,to,cap,0}); 19 edges.push_back(Edge {to,from,c,0}); 20 m=edges.size(); 21 G[from].push_back(m-2); 22 G[to].push_back(m-1); 23 } 24 25 bool BFS() 26 { 27 memset(vis,0,sizeof(vis)); 28 queue<int> Q; 29 Q.push(s); 30 d[s]=0; 31 vis[s]=1; 32 while(!Q.empty()) 33 { 34 int x=Q.front();Q.pop(); 35 for(int i=0;i<G[x].size();i++) 36 { 37 Edge& e=edges[G[x][i]]; 38 if(!vis[e.to]&&e.cap>e.flow) 39 { 40 vis[e.to]=1; 41 d[e.to]=d[x]+1; 42 Q.push(e.to); 43 } 44 } 45 } 46 return vis[t]; 47 } 48 49 int DFS(int x,int a) 50 { 51 if(x==t||a==0) return a; 52 int flow=0,f; 53 for(int& i=cur[x];i<G[x].size();i++) 54 { 55 Edge& e=edges[G[x][i]]; 56 if(d[x]+1==d[e.to]&&(f=DFS(e.to,min(a,e.cap-e.flow)))>0) 57 { 58 e.flow+=f; 59 edges[G[x][i]^1].flow-=f; 60 flow+=f; 61 a-=f; 62 if(a==0) break; 63 } 64 } 65 return flow; 66 } 67 int Maxflow(int s,int t) 68 { 69 this->s=s;this->t=t; 70 int flow=0; 71 while(BFS()) 72 { 73 memset(cur,0,sizeof(cur)); 74 flow+=DFS(s,INF); 75 } 76 return flow; 77 } 78 }; 79 80 int maze[55][55]; 81 int main() 82 { 83 //freopen("data.in","r",stdin); 84 //freopen("data.out","w",stdout); 85 int n,m; 86 while(~scanf("%d%d",&n,&m)) 87 { 88 int s=n*m+10,t=n*m+20; 89 int tot=0; 90 DINIC F; 91 for(int i=0;i<n;i++) 92 { 93 for(int j=0;j<m;j++) 94 { 95 scanf("%d",&maze[i][j]); 96 tot+=maze[i][j]; 97 if((i+j)%2==0) 98 { 99 if(j<m-1) F.AddEdge(i*m+j,i*m+j+1,INF); 100 if(i<n-1) F.AddEdge(i*m+j,i*m+m+j,INF); 101 if(i>0) F.AddEdge(i*m+j,i*m-m+j,INF); 102 if(j>0) F.AddEdge(i*m+j,i*m+j-1,INF); 103 F.AddEdge(s,i*m+j,maze[i][j]); 104 } 105 else F.AddEdge(i*m+j,t,maze[i][j]); 106 } 107 } 108 int ans=tot-F.Maxflow(s,t); 109 printf("%d\n",ans); 110 } 111 }