HDU1565 方格取数(1) 网络流
2015-07-25 14:32
495 查看
[code]//将问题转化为最小割,首先采用奇偶建立二分图, //最大点独立集=总权-最小点权覆盖集 //二分图最小点权覆盖:从x或y中选取一些点,使这些点覆盖所有的边, //并且选出来的点权值和最小 #include <map> #include <set> #include <stack> #include <queue> #include <cmath> #include <ctime> #include <vector> #include <cstdio> #include <cctype> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> using namespace std; #define INF 0x3f3f3f3f #define inf -0x3f3f3f3f #define lson k<<1, L, mid #define rson k<<1|1, mid+1, R #define mem0(a) memset(a,0,sizeof(a)) #define mem1(a) memset(a,-1,sizeof(a)) #define mem(a, b) memset(a, b, sizeof(a)) typedef long long ll; const int maxn=1000 + 10; struct Edge{ int from,to,cap,flow; Edge(int u,int v,int c,int f):from(u),to(v),cap(c),flow(f){} }; struct Dinic{ int n,m,s,t; //结点数,边数(包括反相弧),源点编号和汇点编号 vector<Edge>edges; //边表,edges[e]和edges[e^1]互为反相弧 vector<int>G[maxn]; //邻接表,G[i][j]表示结点i的第j条边在e数组中的序号 bool vis[maxn]; //BFS使用 int d[maxn]; //从起点到i的距离 int cur[maxn]; //当前弧下标 void AddEdge(int from,int to,int cap){ edges.push_back(Edge(from,to,cap,0)); edges.push_back(Edge(to,from,0,0)); m=edges.size(); G[from].push_back(m-2); G[to].push_back(m-1); } void init(int n){ this->n=n; for(int i=0;i<=n;i++) G[i].clear(); edges.clear(); } bool BFS(){ mem0(vis); queue<int>Q; Q.push(s); d[s]=0; vis[s]=1; while(!Q.empty()){ int x=Q.front(); Q.pop(); for(int i=0;i<G[x].size();i++){ //只考虑残量网络中的弧 Edge& e=edges[G[x][i]]; if(!vis[e.to]&&e.cap>e.flow){ vis[e.to]=1; d[e.to]=d[x]+1; Q.push(e.to); } } } return vis[t]; } ll DFS(int x,int a){ if(x==t||a==0) return a; ll flow=0,f; for(int& i=cur[x];i<G[x].size();i++){ Edge& e=edges[G[x][i]]; if(d[x]+1==d[e.to]&&(f=DFS(e.to,min(a,e.cap-e.flow)))>0){ e.flow+=f; edges[G[x][i]^1].flow-=f; flow+=f; a-=f; if(a==0) break; } } return flow; } ll Maxflow(int s,int t){ this->s=s; this->t=t; ll flow=0; while(BFS()){ mem0(cur); flow+=DFS(s,INF); } return flow; } }; Dinic solve; int mp[21][21]; int main(){ int x,y,z; int n,m; while(scanf("%d",&n)!=EOF){ solve.init(n*n+1); //初始化不要错误 int sum=0; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++){ scanf("%d",&mp[i][j]); if((i+j)%2==0){ solve.AddEdge(0,(i-1)*n+j,mp[i][j]); } else solve.AddEdge((i-1)*n+j,n*n+1,mp[i][j]); sum+=mp[i][j]; } for(int i=1;i<=n;i++) for(int j=1;j<=n;j++){ if((i+j)%2==0){ if(i-1>=1){ solve.AddEdge((i-1)*n+j,(i-2)*n+j,INF); } if(i+1<=n){ solve.AddEdge((i-1)*n+j,i*n+j,INF); } if(j-1>=1){ solve.AddEdge((i-1)*n+j,(i-1)*n+j-1,INF); } if(j+1<=n) solve.AddEdge((i-1)*n+j,(i-1)*n+j+1,INF); } } ll tmp=solve.Maxflow(0,n*n+1); printf("%d\n",sum-tmp); } return 0; }
相关文章推荐
- python基础教程总结13——网络编程,
- http协议的一些基础介绍
- iOS- 网络访问JSON数据类型与XML数据类型的实现思路及它们之间的区别
- vsftpd安装与配置--研究tcp与防火墙
- HttpURLConnection 下载
- 使用TCP/IP的套接字(Socket)进行通信
- nyoj170 网络的可靠性(第三届河南省程序设计大赛)
- 没有任何关闭socket的日志,客户端和服务端进程都在, 网络连接完好, 为什么进行某操作后好好的tcp连接莫名其妙地断了呢?
- Apache 开启 Https
- 程序员笔试面试系列-网络与通信知识点
- Windows无法连接到选定网络,网络可能不在区域中。请刷新可用网络的列表,重新尝试
- TCP Segment Offload(TSO)的实现原理浅析
- TCP Segment Offload(TSO)的实现原理浅析
- Linux网络流量实时监控工具-ifstat
- Linux下的网络配置命令
- android 网络异步加载数据进度条
- nyoj-170-网络的可靠性(找度数1)
- 通过AFNetworking发送和获取网络资源
- 网络拍卖系统的设计
- 手动配置linux 网络时,修改默认网关,设置防火墙