标签:方格取数 put ack content back blank add log 测试
嗯,这是关于最大点权独立集与最小点权覆盖集的姿势,很简单对吧,然后开始看题。
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
1 #include<cstdio> 2 #include<cstring> 3 #include<vector> 4 #include<queue> 5 #define MAX 53*53 6 #define INF 0x3f3f3f3f 7 using namespace std; 8 int m,n,map[53][53],sum; 9 int d[4][2]={{0,+1},{+1,0},{0,-1},{-1,0}}; 10 struct Edge{ 11 int u,v,c,f; 12 }; 13 struct Dinic 14 { 15 int s,t; 16 vector<Edge> E; 17 vector<int> G[MAX]; 18 bool vis[MAX]; 19 int lev[MAX]; 20 int cur[MAX]; 21 void init(int l,int r) 22 { 23 E.clear(); 24 for(int i=l;i<=r;i++) G[i].clear(); 25 } 26 void addedge(int from,int to,int cap) 27 { 28 E.push_back((Edge){from,to,cap,0}); 29 E.push_back((Edge){to,from,0,0}); 30 G[from].push_back(E.size()-2); 31 G[to].push_back(E.size()-1); 32 } 33 bool bfs() 34 { 35 memset(vis,0,sizeof(vis)); 36 queue<int> q; 37 q.push(s); 38 lev[s]=0; 39 vis[s]=1; 40 while(!q.empty()) 41 { 42 int now=q.front(); q.pop(); 43 for(int i=0,_size=G[now].size();i<_size;i++) 44 { 45 Edge edge=E[G[now][i]]; 46 int nex=edge.v; 47 if(!vis[nex] && edge.c>edge.f) 48 { 49 lev[nex]=lev[now]+1; 50 q.push(nex); 51 vis[nex]=1; 52 } 53 } 54 } 55 return vis[t]; 56 } 57 int dfs(int now,int aug) 58 { 59 if(now==t || aug==0) return aug; 60 int flow=0,f; 61 for(int& i=cur[now],_size=G[now].size();i<_size;i++) 62 { 63 Edge& edge=E[G[now][i]]; 64 int nex=edge.v; 65 if(lev[now]+1 == lev[nex] && (f=dfs(nex,min(aug,edge.c-edge.f)))>0) 66 { 67 edge.f+=f; 68 E[G[now][i]^1].f-=f; 69 flow+=f; 70 aug-=f; 71 if(!aug) break; 72 } 73 } 74 return flow; 75 } 76 int maxflow() 77 { 78 int flow=0; 79 while(bfs()) 80 { 81 memset(cur,0,sizeof(cur)); 82 flow+=dfs(s,INF); 83 } 84 return flow; 85 } 86 }dinic; 87 int inmap(int i,int j) 88 { 89 if(1<=i && i<=m && 1<=j && j<=n) return (i-1)*n+j; 90 else return 0; 91 } 92 int main() 93 { 94 while(scanf("%d%d",&m,&n)!=EOF)//m行n列 95 { 96 dinic.init(0,m*n+1); 97 sum=0; 98 dinic.s=0, dinic.t=m*n+1; 99 for(int i=1;i<=m;i++) 100 { 101 for(int j=1;j<=n;j++) 102 { 103 scanf("%d",&map[i][j]); 104 sum+=map[i][j]; 105 int id=(i-1)*n+j; 106 if((i+j)%2) 107 { 108 for(int k=0,_id;k<4;k++) if(_id=inmap(i+d[k][0],j+d[k][1])) dinic.addedge(id,_id,INF); 109 dinic.addedge(dinic.s,id,map[i][j]); 110 } 111 else dinic.addedge(id,dinic.t,map[i][j]); 112 } 113 } 114 printf("%d\n",sum-dinic.maxflow()); 115 } 116 }
HDU 1569 - 方格取数(2) - [最大点权独立集与最小点权覆盖集]
标签:方格取数 put ack content back blank add log 测试
原文地址:http://www.cnblogs.com/dilthey/p/7401563.html