• [01分数规划二分]网络战争


    网络战争

    给一个无向图 (G=(V,E)) ,求一个边集 (C) ,删除 (C)(s)(t) 不再连通

    最小化

    [dfrac {sum_{ein C}w_e} {|C|} ]

    01分数规划

    每个物品价值 (w_i) , 花费 (c_i)

    选一些物品使得

    (dfrac{sum w} {sum c}) 最小

    [dfrac {sum w} {sum c} < lambda \ sum w - lambda sum c < 0 \ sum_i (w_i - lambda c_i) < 0 ]

    至此,可以二分答案 (lambda)

    /*
     * @Author: zhl
     * @Date: 2020-10-22 15:44:57
     */
    
    #include<bits/stdc++.h>
    #define rep(i,a,b) for(int i = a;i <= b;i++)
    #define repE(i,u) for(int i = head[u]; ~i; i = E[i].next)
    using namespace std;
    
    const int N = 2100, M = 10100, inf = 1e9;
    struct Edge {
    	int to, next;
    	double flow;
    }E[M << 1];
    int head[N], tot;
    void addEdge(int from, int to, double w) {
    	E[tot] = Edge{ to,head[from],w };
    	head[from] = tot++;
    	E[tot] = Edge{ from,head[to],0.0 };
    	head[to] = tot++;
    }
    
    int n, m, s, t;
    queue<int>Q;
    int dis[N], cur[N];
    bool bfs() {
    	memset(dis, -1, sizeof dis);
    	while (!Q.empty())Q.pop();
    	Q.push(s); dis[s] = 0; cur[s] = head[s];
    	while (!Q.empty()) {
    		int u = Q.front(); Q.pop();
    		repE(i, u) {
    			int v = E[i].to;
    			if (dis[v] == -1 and E[i].flow) {
    				cur[v] = head[v];
    				dis[v] = dis[u] + 1;
    				Q.push(v);
    				if (v == t)return true;
    			}
    		}
    	}
    	return false;
    }
    
    double dfs(int u, double limit) {
    	if (u == t)return limit;
    	double k, res = 0;
    	for (int i = cur[u]; ~i and res < limit; i = E[i].next) {
    		int v = E[i].to;
    		cur[u] = i;
    		if (dis[v] == dis[u] + 1 and E[i].flow) {
    			k = dfs(v, min(limit - res, E[i].flow));
    			if (k == 0)dis[v] = -1;
    			E[i].flow -= k; E[i ^ 1].flow += k;
    			res += k;
    		}
    	}
    	return res;
    }
    
    double Dinic() {
        double res = 0, f;
    	while (bfs())while (f = dfs(s, inf)) res += f;
    	return res;
    }
    
    const double eps = 1e-4;
    int u[N],v[N],w[N];
    
    bool judge(double x){
        memset(head,-1,sizeof head);
        tot = 0;
        double sum = 0;
        rep(i,1,m){
            if(w[i] <= x) sum += w[i] - x;
            else addEdge(u[i],v[i],w[i]-x),addEdge(v[i],u[i],w[i]-x);
        }
        return Dinic() + sum <= 0;
    }
    int main(){
        scanf("%d%d%d%d",&n,&m,&s,&t);
        rep(i,1,m){
            scanf("%d%d%d",u+i,v+i,w+i);
        }
        double l = 0,r = 1e7;
        while(r - l > eps){
            double mid = (l + r) / 2;
            if(judge(mid))r = mid;
            else l = mid;
        }
        printf("%.2f
    ",l);
    }
    
  • 相关阅读:
    动车上的书摘-java对象流与序列化
    动车上的书摘-java网络 连接服务器
    HP-Socket v3.2.2
    古典音乐 (java基础 继承)
    编写高质量代码改善java程序的151个建议——[52-57]String !about String How to use them?
    项目ITP(七) javaWeb 整合 Quartz 实现动态调度 并且 持久化
    HP-JavaUtil: xls 操作类
    [ Talk is Cheap Show me the CODE ] : jQuery Mobile工具栏
    [ Talk is Cheap Show me the CODE ] : jQuery Mobile页面布局
    20140622
  • 原文地址:https://www.cnblogs.com/sduwh/p/13878958.html
Copyright © 2020-2023  润新知