• zoj 2676 Network Wars 最小割+0-1分数规划


    题目链接: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2676

    题意:

    给出N个点和M条边,要求一个割集,使得集合中 ans = 所有边点权值和/边的数量 最小。

    思路:

    0-1分数规划。

    具体证明参考 胡伯涛 《最小割模型在信息学竞赛中的应用

    设g = min(Σwi/Σ1)

    转化为 求g使得 (Σwi - g*Σ1) = 0。

    所以二分求g的值。

    每次建图的时候,以1为源点,N为汇点。

    原来图中每条边的容量 = wi-g。

    要注意点是如果容量<0,那么这条边必在割集中。

    如果容量>=0,在图中连起来然后求最小割。

    最后输出边集。

      1 #include <iostream>
      2 #include <cstring>
      3 #include <string>
      4 #include <cstdio>
      5 #include <queue>
      6 #include <cmath>
      7 #include <algorithm>
      8 #include <vector>
      9 using namespace std;
     10 #define maxn 105
     11 const double inf = 10000007;
     12 const double eps = 1e-8;
     13 struct Edge
     14 {
     15     int from, to, xh;
     16     double cap, flow;
     17     Edge(int f, int t, double c, double fl, int x)
     18     {
     19         from = f; to = t; cap = c; flow = fl; xh = x;
     20     }
     21 };
     22 struct Edge2
     23 {
     24     int from, to;
     25     double cost;
     26 }init[405];
     27 vector <Edge> edges;
     28 vector <int> G[maxn];
     29 int n, m, s, t;
     30 int vis[maxn], cur[maxn], d[maxn];
     31 double min(double a, double b)
     32 {
     33     return a<b?a:b;
     34 }
     35 void AddEdge(int from, int to, double cap, int xh)
     36 {
     37     edges.push_back(Edge(from, to, cap, 0, xh));
     38     edges.push_back(Edge(to, from, 0, 0, -1));
     39     m = edges.size();
     40     G[from].push_back(m-2);
     41     G[to].push_back(m-1);
     42 }
     43 bool bfs()
     44 {
     45     memset(vis, 0, sizeof(vis));
     46     d[s] = 0;
     47     vis[s] = 1;
     48     queue <int> q;
     49     q.push(s);
     50     while(!q.empty())
     51     {
     52         int u = q.front(); q.pop();
     53         for(int i = 0; i < G[u].size(); i++)
     54         {
     55             Edge &e = edges[G[u][i]];
     56             if(!vis[e.to] && e.cap-e.flow > eps)
     57             {
     58                 vis[e.to] = 1; 
     59                 d[e.to] = d[u]+1;
     60                 q.push(e.to);
     61             }
     62         }
     63     }
     64     return vis[t];
     65 }
     66 double dfs(int x, double a)
     67 {
     68     if(x == t || fabs(a) <eps) return a;
     69     double flow = 0, f;
     70     for(int &i = cur[x]; i < G[x].size(); i++)
     71     {
     72         Edge &e = edges[G[x][i]];
     73         if(d[x]+1 == d[e.to] && (f = dfs(e.to, min(a, e.cap - e.flow))) > eps)
     74         {
     75             e.flow += f;
     76             edges[G[x][i]^1].flow -= f;
     77             flow += f;
     78             a -= f;
     79             if(fabs(a) < eps) break;
     80         }
     81     }
     82     return flow;
     83 }
     84 double Maxflow()
     85 {
     86     double flow = 0;
     87     while(bfs())
     88     {
     89         memset(cur, 0, sizeof(cur));
     90         flow += dfs(s, inf);
     91     }
     92     return flow;
     93 }
     94 int N, M;
     95 int main()
     96 {
     97     while(~scanf("%d%d", &N, &M))
     98     {
     99         for(int i = 1; i <= M; i++)
    100         {
    101             scanf("%d%d%lf", &init[i].from, &init[i].to, &init[i].cost);
    102         }
    103         double l = 0, r = 10000001;
    104         s = 1, t = N; n = N;
    105         double mid;
    106         double sum = 0;
    107         while(l+eps <= r)
    108         {
    109             edges.clear();
    110             for(int i = 1; i <= N; i++) G[i].clear();
    111             mid = (l+r)/2.0;
    112             sum = 0;
    113             for(int i = 1; i <= M; i++)
    114             {
    115                 double temp = init[i].cost - mid;
    116                 if(temp < 0) sum += temp;
    117                 else
    118                 {
    119                     AddEdge(init[i].from, init[i].to, temp, i);
    120                     AddEdge(init[i].to, init[i].from, temp, i);
    121                 }
    122             }
    123             sum += Maxflow();
    124             if(sum >= eps) l = mid;
    125             else r = mid;
    126         }
    127         vector <int> ans;
    128         edges.clear();
    129         for(int i = 1; i <= N; i++) G[i].clear();
    130         for(int i = 1; i <= M; i++)
    131         {
    132             double temp = init[i].cost - mid;
    133             if(temp >= 0)
    134             {
    135                 AddEdge(init[i].from, init[i].to, temp, i);
    136                 AddEdge(init[i].to, init[i].from, temp, i);
    137             }
    138         }
    139         Maxflow();
    140         int cnt = 0;
    141         for(int i = 1; i <= M; i++)
    142         {
    143             if((vis[init[i].from] + vis[init[i].to]) == 1 || init[i].cost + eps < mid)
    144             {
    145                 cnt++;
    146             }
    147         }
    148         printf("%d
    ", cnt);
    149         bool flag = true;
    150         for(int i = 1; i <= M; i++)
    151         {
    152             if((vis[init[i].from] + vis[init[i].to]) == 1 || init[i].cost + eps < mid)
    153             {
    154                 if(flag)
    155                 {
    156                     printf("%d", i);
    157                     flag = false;
    158                 }
    159                 else printf(" %d", i);
    160             }
    161         }
    162         printf("
    ");
    163         
    164     }
    165 
    166     return 0;
    167 }
  • 相关阅读:
    SpringBoot最新教程IDEA版【狂神说Java系列】
    Mybatis最新完整教程IDEA版【通俗易懂2019.11月】
    freemarker 数字格式化(金额格式化)
    idea皮肤插件
    Spring Security 自定义表单登录页
    Spring Security 用户配置
    Spring Security 初体验
    Tomcat 部署 Spring Boot工程
    服务器安装Ngnix
    java读取配置文件
  • 原文地址:https://www.cnblogs.com/titicia/p/4705103.html
Copyright © 2020-2023  润新知