TakeoffYoung

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

题意:

  给定一个无向带权图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\n", res1, res2);    
159     }
160 }
View Code

 

posted on 2015-07-22 13:16  TakeoffYoung  阅读(227)  评论(0编辑  收藏  举报