zoukankan      html  css  js  c++  java
  • 【题解】Catering World Finals 2015 上下界费用流

    Prelude

    传送到Codeforces:0.0


    Solution

    板子题,在这里贴个板子。
    这题面是smg?题面中有说每个点只能经过一次吗?是我瞎了吗?
    因为这WA on test 27一个小时,烦死了,浪费时间。


    Code

    #include <cstring>
    #include <algorithm>
    #include <cstdio>
    #include <queue>
    #include <cassert>
    
    using namespace std;
    const int MAXN = 1000;
    const int MAXM = 100000;
    const int INF = 0x3f3f3f3f;
    int _w;
    
    int read() {
    	int x;
    	_w = scanf( "%d", &x );
    	return x;
    }
    
    namespace MCMF {
    	struct Edge {
    		int u, v, c, f, w;
    		Edge() {}
    		Edge( int u, int v, int c, int f, int w ):
    			u(u), v(v), c(c), f(f), w(w) {}
    	};
    	
    	int n, m, s, t;
    	int head[MAXN], nxt[MAXM];
    	Edge edge[MAXM];
    	
    	void init( int _n ) {
    		n = _n, m = 0;
    		for( int i = 0; i < n; ++i )
    			head[i] = -1;
    	}
    	void adde( int u, int v, int c, int w ) {
    		edge[m] = Edge(u, v, c, 0, w);
    		nxt[m] = head[u], head[u] = m++;
    		edge[m] = Edge(v, u, 0, 0, -w);
    		nxt[m] = head[v], head[v] = m++;
    	}
    	
    	queue<int> q;
    	int dis[MAXN], inq[MAXN], res[MAXN], from[MAXN];
    	
    	bool spfa() {
    		for( int i = 0; i < n; ++i )
    			dis[i] = INF, inq[i] = 0;
    		dis[s] = 0, inq[s] = 1, q.push(s), res[s] = INF;
    		while( !q.empty() ) {
    			int u = q.front(); q.pop();
    			inq[u] = 0;
    			for( int i = head[u]; ~i; i = nxt[i] ) {
    				const Edge &e = edge[i];
    				if( e.c > e.f && dis[u] + e.w < dis[e.v] ) {
    					dis[e.v] = dis[u] + e.w;
    					from[e.v] = i;
    					res[e.v] = min( res[u], e.c-e.f );
    					if( !inq[e.v] )
    						inq[e.v] = 1, q.push(e.v);
    				}
    			}
    		}
    		return dis[t] != INF;
    	}
    	void augment() {
    		int f = res[t], u = t;
    		while( u != s ) {
    			int i = from[u];
    			edge[i].f += f;
    			edge[i^1].f -= f;
    			u = edge[i].u;
    		}
    	}
    	int solve( int _s, int _t ) {
    		s = _s, t = _t;
    		int cost = 0;
    		while( spfa() ) {
    			cost += res[t] * dis[t];
    			augment();
    		}
    		return cost;
    	}
    }
    
    int n, k, g[MAXN][MAXN];
    int s, t, ss, tt, nid;
    int in[MAXN], out[MAXN];
    
    void adde( int u, int v, int l, int r, int w ) {
    	MCMF::adde(ss, v, l, 0);
    	MCMF::adde(u, tt, l, 0);
    	MCMF::adde(u, v, r-l, w);
    }
    
    void solve() {
    	s = nid++, t = nid++, ss = nid++, tt = nid++;
    	for( int i = 1; i <= n; ++i )
    		in[i] = nid++, out[i] = nid++;
    	MCMF::init(nid);
    	adde(t, s, 0, INF, 0);
    	adde(s, out[1], 0, k, 0);
    	for( int i = 2; i <= n; ++i ) {
    		adde(out[i], t, 0, INF, 0);
    		adde(in[i], out[i], 1, 1, 0); // 每个点只能经过一次
    	}
    	for( int i = 1; i <= n; ++i )
    		for( int j = i+1; j <= n; ++j )
    			adde(out[i], in[j], 0, INF, g[i][j]);
    	printf( "%d
    ", MCMF::solve(ss, tt) );
    }
    
    int main() {
    	n = read()+1, k = read();
    	for( int i = 1; i <= n; ++i )
    		for( int j = i+1; j <= n; ++j )
    			g[i][j] = read();
    	solve();
    	return 0;
    }
    
  • 相关阅读:
    局域网文件实时同步工具
    SQLServer备份恢复助手(太强大了!)
    SQLServer 统计查询语句消耗时间
    如何将Sql server数据库中的模型图转化到Word中--并能够查看字段的属性信息
    创建Database Diagrams时遇到的问题
    bat 操作数据库(附加,分离,删除,还原)
    Bat 多个执行操作选择
    Redis Windows下查看版本号
    ThinkPHP 数据库操作(七) : 视图查询、子查询、原生查询
    ThinkPHP 数据库操作(六) : 查询事件、事务操作、监听SQL
  • 原文地址:https://www.cnblogs.com/mlystdcall/p/8137626.html
Copyright © 2011-2022 走看看