zoukankan      html  css  js  c++  java
  • hdu 5296,15年多校1-7

    题意:

      给定一个无向带权图G(n, m),一个人要沿着最短路从1走到n,现在可以任意从图上删边。求,最少删多少边可以使之无法到达终点  和   最多删多少边其仍可以到达终点

    想法:

      比赛时的想法:直接跑最小费用最大流,spfa的时候维护一个最短路的值(min_dist),如果当前求得增广路径的最短路的值大于min_dist,肯定后面的最短路就都大于min_dist了,此时就已经求出最大流即第一问的答案了。在求增广路径的过程中维护所有最短路的最小边数,总边数减去最小边数就是即为第二问的答案。(没有觉得思路有什么问题,赛后对着数据,总是有两组跑的特别慢并且答案也是错的)。

      后来按照标程写了一个,先一遍spfa求出所有最短录,并且得到最少边数。然后遍历所有边将最短路建图(这个图是根据最短路中dist值建的有向图),在新图上跑一遍最大流。结果两组数据还是过不去。

    现记下来,回头补上。

    武大训练第10场又挂了这个题,比赛时候补上了。

    这是题解说的先最短路,重新建图再跑网络流的做法

    2015-9-12 补充,费用流没法做,因为在求增广路的时候会改变图中最短路上边的数量。对网络流还是不够熟悉

      1 #include <bits/stdc++.h>
      2 
      3 const int MAXN = 2000+100;
      4 const int MAXM = 200000+100;
      5 const int INF = 0x3f3f3f3f;
      6 
      7 typedef std::pair<int, int> pii;
      8 
      9 struct Edge{
     10     int u, v, cap, next;
     11     Edge(){}
     12     Edge(int u, int v, int cap, int next)
     13     {
     14         this->u = u;
     15         this->v = v;
     16         this->cap = cap;
     17         this->next = next;
     18     }
     19 }edge[MAXM];
     20 int head[MAXN];
     21 int tot;
     22 std::vector<pii> ve[MAXN];
     23 int dep[MAXN];
     24 int n, m;
     25 int dist[MAXN];
     26 bool vis[MAXN];
     27 int road[MAXN];
     28 
     29 void addEdge(int u, int v, int cap)
     30 {
     31     edge[++tot] = Edge(u, v, cap, head[u]);
     32     head[u] = tot;
     33 }
     34 
     35 int dfs(int u, int sink, int min_flow) 
     36 {
     37     if (u == sink) {
     38         return min_flow;
     39     }
     40     int res = 0;
     41     for (int i = head[u]; i > 0 && min_flow > 0; i = edge[i].next) {
     42         if (dep[edge[i].v] == dep[u] + 1) {
     43             int dd = dfs(edge[i].v, sink, std::min(min_flow, edge[i].cap));
     44             edge[i].cap -= dd;
     45             edge[i^1].cap += dd;
     46             res += dd;
     47             min_flow -= dd;
     48         }
     49     }
     50     return res;
     51 }
     52 
     53 void bfs(int src, int sink)
     54 {
     55     memset(dep, 0, sizeof dep);
     56     std::queue<int> que;
     57     que.push(src);
     58     dep[src] = 1;
     59     while (que.empty() == false) {
     60         int u = que.front();
     61         que.pop();
     62         for (int i = head[u]; i > 0; i = edge[i].next) {
     63             int v = edge[i].v;
     64             int cap = edge[i].cap;
     65             if (dep[v] == 0 && cap > 0) {
     66                 dep[v] = dep[u] + 1;
     67                 if (v == n) {
     68                     return;
     69                 }
     70                 que.push(v);
     71             }
     72         }
     73     }
     74 }
     75 
     76 int dinic(int src, int sink)
     77 {
     78     int res = 0;
     79     while (true) {
     80         bfs(src, sink);
     81         if (dep[sink] == 0) {
     82             return res;
     83         }
     84         res += dfs(src, sink, INF);
     85     }
     86 }
     87 
     88 void init()
     89 {
     90     tot = 1;
     91     memset(head, 0, sizeof head);
     92     for (int i = 1; i <= n; ++ i) {
     93         ve[i].clear();
     94     }
     95 }
     96 
     97 int main()
     98 {
     99     while (~scanf("%d%d" , &n, &m)) {
    100         init();
    101         for (int i = 1; i <= m; ++ i) {
    102             int u, v, cost;
    103             scanf("%d%d%d", &u, &v, &cost);
    104             if (u == v) 
    105                 continue;
    106             ve[u].push_back(std::make_pair(v, cost));
    107             ve[v].push_back(std::make_pair(u, cost));
    108         }
    109         memset(vis, false, sizeof vis);
    110         for (int i = 1; i <= n; ++ i) {
    111             dist[i] = INF;
    112             road[i] = INF;
    113         }
    114         dist[1] = 0;
    115         road[1] = 0;
    116         std::queue<int> que;
    117         que.push(1);
    118         vis[1] = true;
    119         while (que.empty() == false) {
    120             int u = que.front();
    121             que.pop();
    122             vis[u] = false;
    123             for (int i = 0; i < (int)ve[u].size(); ++ i) {
    124                 int v = ve[u][i].first;
    125                 if (dist[v] > dist[u] + ve[u][i].second) {
    126                     dist[v] = dist[u] + ve[u][i].second;
    127                     if (vis[v] == false ) {
    128                         vis[v] = true;
    129                         que.push(v);
    130                     }
    131                 }
    132             }
    133         }
    134 
    135         que.push(1);
    136         memset(vis, false, sizeof vis);
    137         memset(road, 0x3f3f3f3f, sizeof road);
    138         road[1] = 0;
    139         vis[1] = true;
    140         while (que.empty() == false) {
    141             int u = que.front();
    142             que.pop();
    143             for (int i = 0; i < (int)ve[u].size(); ++ i) {
    144                 int v = ve[u][i].first;
    145                 int w = ve[u][i].second;
    146                 if (dist[v] == dist[u] + w) {
    147                     addEdge(u, v, 1);
    148                     addEdge(v, u, 0);
    149 
    150                     vis[v] = true;
    151                     que.push(v);
    152                     road[v] = std::min(road[v], road[u] + 1);
    153                 }
    154             }
    155         }
    156         int res2 =  m - road[n];
    157         int res1 = dinic(1, n);
    158         printf("%d %d
    ", res1, res2);    
    159     }
    160 }
    View Code
  • 相关阅读:
    html js 执行粘贴无效和 判断选中的内容(纯文本和html)是否为空
    Javascript中document.execCommand()的用法
    bootstrap4 按钮默认有个动画效果
    vue 源码初级学习
    gitextention 常用技巧
    状态模式全解析--JavaScript
    51..分治算法练习:  4378 【Laoguo】循环比赛
    51..分治算法练习:  4378 【Laoguo】循环比赛
    50.分治算法练习:  二分算法:  2703 奶牛代理商 XII
    50.分治算法练习:  二分算法:  2703 奶牛代理商 XII
  • 原文地址:https://www.cnblogs.com/takeoffyoung/p/4667131.html
Copyright © 2011-2022 走看看