码迷,mamicode.com
首页 > 其他好文 > 详细

2019HDU多校第一场 6582 Path 【最短路+最大流最小割】

时间:2019-08-09 01:37:30      阅读:108      评论:0      收藏:0      [点我收藏+]

标签:space   +=   gre   eve   back   targe   NPU   const   最大流   

一、题目

  Path

二、分析

  首先肯定要求最短路,然后如何确定所有的最短路其实有多种方法。

  1 根据最短路,那么最短路上的边肯定是可以满足$dist[from] + e.cost = dist[to]$。所以可以求一遍后根据这个公式再向网络图中的加边即可。

  2 可以从源点和汇点分别求最短路,然后根据每条边肯定满足$dist1[e.from] + e.cost + dist2[e.to] = dij$,再加边就行了。

  确定最短路后,由于是求最小割,直接跑$Dinic$求出最大流就可以了。

三、AC代码

  1 #include <bits/stdc++.h>
  2 
  3 using namespace std;
  4 #define Min(a, b) ((a)>(b)?(b):(a))
  5 #define P pair<ll, int>
  6 #define ll long long
  7 const ll INF = __LONG_LONG_MAX__;
  8 const int maxn = 2e4 + 13;
  9 const int maxm = 2e4 + 13;
 10 int N, M;
 11 
 12 struct edge
 13 {
 14     int to, cost;
 15 };
 16 struct edge2
 17 {
 18     ll to, cap, rev;
 19 };
 20 ll dist1[maxn], dist2[maxn];
 21 vector<edge> G1[maxn], G2[maxn];    //G1正向图,G2反向图
 22 vector<edge2> G[maxn << 2];
 23 
 24 void addedge(ll from, ll to, ll cap)
 25 {
 26     G[from].push_back((edge2){to, cap, (ll)G[to].size()});
 27     G[to].push_back((edge2){from, 0, (ll)G[from].size()-1});
 28 }
 29 
 30 void dijkstra()
 31 {
 32     priority_queue<P, vector<P>, greater<P>> pque;
 33     pque.push(P(0, 1));
 34     fill(dist1, dist1 + N + 2, INF);
 35     dist1[1] = 0;
 36     while(!pque.empty())
 37     {
 38         P q = pque.top();
 39         pque.pop();
 40         int v = q.second;
 41         if(dist1[v] < q.first)
 42             continue;
 43         for(int i = 0; i < G1[v].size(); i++)
 44         {
 45             edge e = G1[v][i];
 46             if(dist1[v] + e.cost < dist1[e.to])
 47             {
 48                 dist1[e.to] = dist1[v] + e.cost;
 49                 pque.push(P(dist1[e.to], e.to));
 50             }
 51         }
 52     }
 53 
 54     // pque.push(P(0, N));
 55     // fill(dist2, dist2 + N + 2, INF);
 56     // dist2[N] = 0;
 57     // while(!pque.empty())
 58     // {
 59     //     P q = pque.top();
 60     //     pque.pop();
 61     //     int v = q.second;
 62     //     if(dist2[v] < q.first)
 63     //         continue;
 64     //     for(int i = 0; i < G2[v].size(); i++)
 65     //     {
 66     //         edge e = G2[v][i];
 67     //         if(dist2[v] + e.cost < dist2[e.to])
 68     //         {
 69     //             dist2[e.to] = dist2[v] + e.cost;
 70     //             pque.push(P(dist2[e.to], e.to));
 71     //         }
 72     //     }
 73     // }
 74 }
 75 
 76 void getGraph()
 77 {
 78     dijkstra();
 79     ll Dij = dist1[N];
 80     for(int i = 1; i <= N; i++)
 81     {
 82         for(int j = 0; j < G1[i].size(); j++)
 83         {
 84             edge e = G1[i][j];
 85             if(dist1[e.to] - dist1[i] == e.cost)
 86             {
 87                 addedge((ll)i, (ll)e.to, (ll)e.cost);
 88             }
 89         }
 90     }
 91     // for(int i = 1; i <= N; i++)
 92     // {
 93     //     for(int j = 0; j < G1[i].size(); j++)
 94     //     {
 95     //         edge e = G1[i][j];
 96     //         if(dist1[i] + e.cost + dist2[e.to] == Dij)
 97     //         {
 98     //             addedge((ll)i, (ll)e.to, (ll)e.cost);
 99     //         }
100     //     }
101     // }
102 }
103 
104 ll level[maxn], iter[maxn<<2];
105 
106 void BFS(ll s)
107 {
108     memset(level, -1, sizeof(level));
109     queue<int> que;
110     que.push(s);
111     level[s] = 0;
112     while(!que.empty())
113     {
114         int v = que.front();
115         que.pop();
116         for(int i = 0; i < G[v].size(); i++)
117         {
118             edge2 e = G[v][i];
119             if(e.cap > 0 && level[e.to] < 0)
120             {
121                 level[e.to] = level[v] + 1;
122                 que.push(e.to);
123             }
124         }
125     }
126 }
127 
128 ll DFS(ll v, ll t, ll f)
129 {
130     if(v == t)
131         return f;
132     for(ll &i = iter[v]; i < G[v].size(); i++)
133     {
134         edge2 &e = G[v][i];
135         if(e.cap > 0 && level[v] < level[e.to])
136         {
137             ll d = DFS(e.to, t, min(f, e.cap));
138             if(d > 0)
139             {
140                 e.cap -= d;
141                 G[e.to][e.rev].cap += d;
142                 return d;
143             }
144         }
145     }
146     return 0;
147 }
148 
149 ll Dinic(ll s, ll t)
150 {
151     ll flow = 0;
152     while(1)
153     {
154         BFS(s);
155         if(level[t] < 0)
156             return flow;
157         memset(iter, 0, sizeof(iter));
158         ll f = DFS(s, t, INF);
159         while(f > 0)
160         {
161             flow += f;
162             f = DFS(s, t, INF);
163         }
164     }
165 }
166 
167 int main()
168 {
169     //freopen("input.txt", "r", stdin);
170     int T;
171     scanf("%d", &T);
172     while(T--)
173     {
174         int from, to, cost;
175         scanf("%d%d", &N, &M);
176         for(int i = 0; i <= N; i++)
177         {
178             G[i].clear();
179             G1[i].clear();
180             G2[i].clear();
181         }
182         for(int i = 0; i < M; i++)
183         {
184             scanf("%d%d%d", &from, &to, &cost);
185             G1[from].push_back( (edge){to, cost});
186             G2[to].push_back( (edge){from, cost});
187         }
188         getGraph();
189         printf("%lld\n", Dinic(1, N));
190     }
191     
192 }

 

2019HDU多校第一场 6582 Path 【最短路+最大流最小割】

标签:space   +=   gre   eve   back   targe   NPU   const   最大流   

原文地址:https://www.cnblogs.com/dybala21/p/11324554.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!