1227 方格取数 2 费用流
来源:互联网 发布:恺英网络借壳泰亚股份 编辑:程序博客网 时间:2024/05/24 06:29
题目链接
要点,每个点之间可以连两条边,这样可以解决很多问题,该题中的数据被取出,则可以连一条有权重的边和若干条无权重的边.
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int MAXN = 10000; const int MAXM = 1000000; const int INF = 0x3f3f3f3f; struct Edge { int to,next,cap,flow,cost; } edge[MAXM]; int head[MAXN],tol; int pre[MAXN],dis[MAXN]; bool vis[MAXN]; int N;//节点总个数,节点编号从0~N-1 void init(int n) { N = n; tol = 0; memset(head,-1,sizeof(head)); } void addedge(int u,int v,int cap,int cost) { edge[tol].to = v; edge[tol].cap = cap; edge[tol].cost = cost; edge[tol].flow = 0; edge[tol].next = head[u]; head[u] = tol++; edge[tol].to = u; edge[tol].cap = 0; edge[tol].cost = -cost; edge[tol].flow = 0; edge[tol].next = head[v]; head[v] = tol++; } bool spfa(int s,int t) { queue<int>q; for(int i = 0; i < N; i++) { dis[i] = INF; vis[i] = false; pre[i] = -1; } dis[s] = 0; vis[s] = true; q.push(s); while(!q.empty()) { int u = q.front(); q.pop(); vis[u] = false; for(int i = head[u]; i != -1; i = edge[i].next) { int v = edge[i].to; if(edge[i].cap > edge[i].flow && dis[v] > dis[u] + edge[i].cost ) { dis[v] = dis[u] + edge[i].cost; pre[v] = i; if(!vis[v]) { vis[v] = true; q.push(v); } } } } if(pre[t] == -1)return false; else return true; } //返回的是最大流,cost存的是最小费用 int minCostMaxflow(int s,int t,int &cost) { int flow = 0; cost = 0; while(spfa(s,t)) { int Min = INF; for(int i = pre[t]; i != -1; i = pre[edge[i^1].to]) { if(Min > edge[i].cap - edge[i].flow) Min = edge[i].cap - edge[i].flow; } for(int i = pre[t]; i != -1; i = pre[edge[i^1].to]) { edge[i].flow += Min; edge[i^1].flow -= Min; cost += edge[i].cost * Min; } flow += Min; } return flow; } int n,k; int mm[100][100]; int main() { // freopen("data.txt","r",stdin); ios_base::sync_with_stdio(false); cin >> n>>k; int s = 0; int t = n*n*2+1; init(n*n*2+10); for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { cin >> mm[i][j]; } } addedge(s,1,k,0); for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { int num =(i-1)*n+j; addedge( num,num + n*n, 1 ,-mm[i][j] ); addedge( num,num + n*n, INF,0 ); } } for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { int fr =(i-1)*n+j + n*n; int to =(i)*n+j; if(i!=n) addedge(fr,to,INF,0 ); fr =(i-1)*n+j + n*n; to =(i-1)*n+j+1; if(j!=n) addedge(fr,to,INF,0 ); } } addedge( 2*n*n,t,INF,0); int ans =0; minCostMaxflow(s,t,ans); cout << -ans << endl; return 0; }
阅读全文
0 0
- 1227 方格取数 2 费用流
- Codevs 1227方格取数 (费用流
- 【费用流】codevs1227 方格取数 2
- 【codevs1227】方格取数2,费用流
- Codevs 1227 方格取数2 [费用流] [拆点]
- 【codevs 1227】方格取数2(费用流)
- Codevs 1227 方格取数 2(费用流)
- Codevs[1227]方格取数2 费用流
- 【codevs1227】方格取数2 费用流(EK)
- 【CODEVS1227】方格取数2(费用流)
- codevs1227(方格取数费用流)
- codevs 1227 方格取数 2 【网络流+费用流基础】
- codevs 1227 方格取数 2(最小费用最大流)
- 【费用流】疯狂的方格取数 vijos 1653
- 洛谷 P2045 方格取数加强版 (费用流)
- wiki 方格取数2 网络流 最大流最小费用流
- CODEVS_1227 方格取数2 网络流 最小费用流 拆点
- Codevs_P1227 方格取数2(拆点网络流+最小费用流)
- Matlab 对路径的操作及读写文件
- Android 必知必会
- C语言-位操作技巧
- 集合源码学习(三):ArrayList
- keepalived+LVS/DR
- 1227 方格取数 2 费用流
- 用proteus来仿真二极管与门电路
- 29. Divide Two Integers
- Flash as3 正则表达式
- ubuntu php7 mysqlli不存在解决办法
- libevent源码学习-----统一事件源及信号绑定函数
- DEBUG参数使用大全
- 做项目的一点心得
- Scanner类