zoukankan      html  css  js  c++  java
  • CQOI2016 不同的最小割 (最小割树模板)(等价流树的Gusfield构造算法)

    题目

    最小割树模板

    算法详解及证明见:

    2016年国家队候选队员论文
    《浅谈无向图最小割问题的一些算法及应用——绍兴一中 王文涛》
    3.2节

    CODE

    #include <bits/stdc++.h>
    using namespace std;
    template<class T>inline void read(T &x) {
    	char ch; while(!isdigit(ch=getchar()));
    	for(x=ch-'0';isdigit(ch=getchar());x=x*10+ch-'0');
    }
    const int MAXN = 855;
    const int MAXM = 8505;
    const int inf = 1e9;
    int n, m, Q;
    int info[MAXN], fir[MAXN], to[MAXM<<1], nxt[MAXM<<1], c[MAXM<<1], C[MAXM<<1], cnt;
    inline void link(int u, int v, int cc, int rc) {
    	to[++cnt] = v; nxt[cnt] = fir[u]; fir[u] = cnt; C[cnt] = cc;
    	to[++cnt] = u; nxt[cnt] = fir[v]; fir[v] = cnt; C[cnt] = rc;
    }
    int dis[MAXN];
    queue<int>q;
    int S, T;
    bool bfs() {
    	memset(dis, -1, sizeof dis);
    	dis[S] = 0; q.push(S);
    	while(!q.empty()) {
    		int u = q.front(); q.pop();
    		for(int i = fir[u], v; i; i = nxt[i])
    			if(c[i] && !(~dis[v=to[i]]))
    				dis[v] = dis[u] + 1, q.push(v);
    	}
    	return ~dis[T];
    }
    bool vis[MAXN];
    int aug(int u, int Max) {
    	if(u == T) return Max;
    	int delta, flow = 0;
    	vis[u] = 1;
    	for(int v, &i = info[u]; i; i = nxt[i])
    		if(c[i] && !vis[v=to[i]] && dis[v] == dis[u]+1 && (delta=aug(v, min(Max-flow, c[i])))) {
    			c[i] -= delta; c[i^1] += delta; flow += delta;
    			if(flow == Max) break;
    		}
    	vis[u] = 0;
    	return flow;
    }
    int maxflow(int ss, int tt) {
    	S = ss, T = tt;
    	int re = 0;
    	while(bfs()) memcpy(info, fir, sizeof info), re += aug(S, inf);
    	return re;
    }
    int fa[MAXN], val[MAXN], ans[MAXN][MAXN], seq[MAXN*MAXN], cur;
    void dfs(int u) {
    	if(vis[u]) return;
    	vis[u] = 1;
    	for(int i = fir[u]; i; i = nxt[i])
    		if(c[i]) dfs(to[i]);
    }
    vector<pair<int,int> >e[MAXN];
    void getans(int u, int ff, int now, int s) {
    	ans[s][u] = now;
    	for(int i = e[u].size()-1, v; i >= 0; --i)
    		if((v=e[u][i].first) != ff)
    			getans(v, u, min(now, e[u][i].second), s);
    }
    int main () {
    		read(n), read(m); cnt = 1;
    		for(int i = 1, u, v, c; i <= m; ++i) {
    			read(u), read(v), read(c);
    			link(u, v, c, c);
    		}
    		fa[1] = 0;
    		for(int i = 2; i <= n; ++i) fa[i] = 1;
    		for(int i = 2; i <= n; ++i) {
    			memcpy(c, C, sizeof c);
    			val[i] = maxflow(i, fa[i]);
    			dfs(i);
    			for(int j = i+1; j <= n; ++j)
    				if(vis[j] && fa[i] == fa[j]) fa[j] = i;
    			memset(vis, 0, sizeof vis);
    		}
    		for(int i = 2; i <= n; ++i)
    			e[fa[i]].push_back(make_pair(i, val[i])),
    			e[i].push_back(make_pair(fa[i], val[i]));
    		cur = 0;
    		for(int i = 1; i <= n; ++i) {
    			getans(i, 0, inf, i);
    			for(int j = i+1; j <= n; ++j)
    				seq[++cur] = ans[i][j];
    		}
    		sort(seq + 1, seq + cur + 1);
    		cur = unique(seq + 1, seq + cur + 1) - seq - 1;
    		printf("%d
    ", cur);
    }
    
  • 相关阅读:
    友盟推送
    主流推送平台分析
    “完成”的定义和测试的职责
    HDU 1069 Monkey and Banana
    HDU 5587 Array
    ACM组队安排(hdu校赛)
    逆袭指数(hdu校赛)
    玩骰子(hdu校赛)
    Codeforce 546 A. Soldier and Bananas
    Codeforce 546 B. Soldier and Badges
  • 原文地址:https://www.cnblogs.com/Orz-IE/p/12039174.html
Copyright © 2011-2022 走看看