zoukankan      html  css  js  c++  java
  • BZOJ3118 Orz the MST 【单纯形 + 生成树】

    题目链接

    BZOJ3118

    题解

    少有的单纯形好题啊
    我们先抽离出生成树
    生成树中的边只可能减,其它边只可能加
    对于不在生成树的边,其权值一定要比生成树中其端点之间的路径上所有的边都大
    然后就是一个最小化的线性规划
    为了防止限制过多
    我们只需对原先生成树中的比该边大的边建立限制即可
    然后就是单纯形 + 对偶

    双倍经验

    #include<algorithm>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<cstdio>
    #include<vector>
    #include<queue>
    #include<cmath>
    #include<map>
    #define LL long long int
    #define REP(i,n) for (int i = 1; i <= (n); i++)
    #define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
    #define cls(s,v) memset(s,v,sizeof(s))
    #define mp(a,b) make_pair<int,int>(a,b)
    #define cp pair<int,int>
    using namespace std;
    const int maxn = 1005,maxm = 10005,NN = 1005;
    const double eps = 1e-10,INF = 1e15;
    inline int read(){
    	int out = 0,flag = 1; char c = getchar();
    	while (c < 48 || c > 57){if (c == '-') flag = 0; c = getchar();}
    	while (c >= 48 && c <= 57){out = (out << 1) + (out << 3) + c - 48; c = getchar();}
    	return flag ? out : -out;
    }
    int h[maxn],ne = 1;
    struct EDGE{int to,nxt,id;}ed[maxn << 1];
    inline void build(int u,int v,int id){
    	ed[++ne] = (EDGE){v,h[u],id}; h[u] = ne;
    	ed[++ne] = (EDGE){u,h[v],id}; h[v] = ne;
    }
    int n,m,N,M;
    int dep[maxn],fa[maxn],id[maxn];
    int U[NN],V[NN],W[NN],F[NN],A[NN],B[NN];
    double a[maxn][maxm];
    void dfs(int u){
    	Redge(u) if ((to = ed[k].to) != fa[u]){
    		fa[to] = u; dep[to] = dep[u] + 1; id[to] = ed[k].id;
    		dfs(to);
    	}
    }
    void Pivot(int l,int e){
    	double t = a[l][e]; a[l][e] = 1;
    	for (int j = 0; j <= n; j++) a[l][j] /= t;
    	for (int i = 0; i <= m; i++) if (i != l && fabs(a[i][e]) > 0){
    		t = a[i][e]; a[i][e] = 0;
    		for (int j = 0; j <= n; j++)
    			a[i][j] -= a[l][j] * t;
    	}
    }
    void simplex(){
    	while (true){
    		int l = 0,e = 0; double mn = INF;
    		for (int j = 1; j <= n; j++) if (a[0][j] > eps){e = j; break;}
    		if (!e) break;
    		for (int i = 1; i <= m; i++) if (a[i][e] > eps && a[i][0] / a[i][e] < mn)
    			mn = a[i][0] / a[i][e],l = i;
    		Pivot(l,e);
    	}
    }
    int main(){
    	N = read(); M = read();
    	REP(i,M){
    		U[i] = read(); V[i] = read(); W[i] = read();
    		F[i] = read(); A[i] = read(); B[i] = read();
    		if (F[i]) build(U[i],V[i],i);
    	}
    	dfs(1);
    	n = M;
    	REP(i,M){
    		if (F[i]) a[i][0] = B[i];
    		else{
    			a[i][0] = A[i];
    			int u = U[i],v = V[i],x;
    			while (u != v){
    				if (dep[u] < dep[v]) swap(u,v);
    				x = id[u];
    				if (W[x] > W[i]){
    					m++; 
    					a[x][m] = a[i][m] = 1;
    					a[0][m] = W[x] - W[i];
    				}
    				u = fa[u];
    			}
    		}
    	}
    	swap(n,m);
    	simplex();
    	printf("%.0lf
    ",-a[0][0]);
    	return 0;
    }
    
    
  • 相关阅读:
    LeetCode 109 Convert Sorted List to Binary Search Tree
    LeetCode 108 Convert Sorted Array to Binary Search Tree
    LeetCode 107. Binary Tree Level Order Traversal II
    LeetCode 106. Construct Binary Tree from Inorder and Postorder Traversal
    LeetCode 105. Construct Binary Tree from Preorder and Inorder Traversal
    LeetCode 103 Binary Tree Zigzag Level Order Traversal
    LeetCode 102. Binary Tree Level Order Traversal
    LeetCode 104. Maximum Depth of Binary Tree
    接口和多态性
    C# 编码规范
  • 原文地址:https://www.cnblogs.com/Mychael/p/9300138.html
Copyright © 2011-2022 走看看