• 【BZOJ 1877】【SDOI 2009】晨跑


    拆点跑$MCMF最小费用最大流$

    复习一下$MCMF$模板啦啦啦~~~

    一些坑:更新$dist$后要接着更新$pre$,不要判断是否在队列中再更新,,,听不懂吧,听不懂就对了,因为只有我才会在这种错误上犯逗$TwT$

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define N 205
    #define M 20005
    #define mo 410
    #define read(x) x=getint()
    using namespace std;
    inline int getint() {int k = 0, fh = 1; char c = getchar();	for(; c < '0' || c > '9'; c = getchar()) if (c == '-') fh = -1; for(; c >= '0' && c <= '9'; c = getchar()) k = k * 10 + c - '0'; return k * fh;}
    struct node {
    	int nxt, to, c, cost;
    } E[(N << 1) + (M << 1)];
    bool vis[mo];
    int point[mo], pre[mo], n, m, cnt = 1, q[mo], dist[mo];
    inline void ins(int x, int y, int z, int c) {
    	E[++cnt].nxt = point[x]; E[cnt].to = y; E[cnt].c = z; E[cnt].cost = c; point[x] = cnt;
    	E[++cnt].nxt = point[y]; E[cnt].to = x; E[cnt].c = 0; E[cnt].cost = -c; point[y] = cnt;
    }
    inline bool spfa(int s, int t) {
    	for(int i = 1; i <= ((n - 1) << 1); ++i)
    		dist[i] = 0x7fffffff;
    	int head = 0, tail = 1;
    	q[1] = s; vis[s] = 1; dist[s] = 0;
    	while (head != tail) {
    		++head; if (head == mo) head = 0;
    		int u = q[head];
    		vis[u] = 0;
    		for(int tmp = point[u]; tmp; tmp = E[tmp].nxt) 
    			if (E[tmp].c > 0) {
    				int v = E[tmp].to;
    				if (dist[u] + E[tmp].cost < dist[v]) {
    					dist[v] = dist[u] + E[tmp].cost;
    					pre[v] = tmp;
    					if (!vis[v]) {
    						++tail; if (tail == mo) tail = 0;
    						q[tail] = v;
    						vis[v] = 1;
    					}
    				}
    			}
    	}
    	return dist[t] != 0x7fffffff;
    }
    inline void MCMF(int s, int t) {
    	int a1 = 0, a2 = 0, flow, now;
    	while (spfa(s, t)) {
    		++a1;
    		flow = 0x7fffffff;
    		for(now = pre[t]; now; now = pre[E[now ^ 1].to])
    			flow = min(flow, E[now].c);
    		for(now = pre[t]; now; now = pre[E[now ^ 1].to])
    			a2 += E[now].cost * flow, E[now].c -= flow, E[now ^ 1].c += flow;
    	}
    	printf("%d %d
    ", a1, a2);
    }
    int main() {
    	read(n); read(m);
    	for(int i = 2; i < n; ++i)
    		ins((i << 1) - 1, i << 1, 1, 0);
    	int u, v, e;
    	for(int i = 1; i <= m; ++i) {
    		read(u); read(v); read(e);
    		if (u == 1)
    			if (v == n) ins(1, 2, 1, e);
    			else ins(1, (v << 1) - 1, 1, e);
    		else if (v == n)
    			ins(u << 1, 2, 1, e);
    		else
    			ins(u << 1, (v << 1) - 1, 1, e);
    	}
    	MCMF(1, 2);
    	return 0;
    }
    

    hhh

  • 相关阅读:
    编程思想
    为什么静态成员、静态方法中不能用this和super关键字
    C#中静态与非静态方法比较
    数组,集合,列表的使用与区别
    2017-3-23 网络IP
    [精彩] 关于DB2的内存分配
    DB2 常用命令
    SQL0973N在 "<堆名>" 堆中没有足够的存储器可用来处理语句
    DB2通用数据库性能调整的常用方法
    创建DB2数据库联合对象
  • 原文地址:https://www.cnblogs.com/abclzr/p/5351627.html
Copyright © 2020-2023  润新知