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

Marriage Match IV HDU - 3416

时间:2020-07-01 17:23:25      阅读:54      评论:0      收藏:0      [点我收藏+]

标签:bool   pair   long   vector   lin   scan   其他   main   pre   

Marriage Match IV

思路:属于最短路径上的边应该满足:dis_A[u] + dis_B[v] + w == dis_A[B],dis_A是出发点到其他点的距离,dis_B是终点到其他点的距离,u,v是边的两个端点,w是权值。题目说每条边只能用一次,我们可以用最大流算法来求最短路径有几条。

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <algorithm>
  4 #include <queue>
  5 #include <vector>
  6 
  7 using namespace std;
  8 
  9 #define ll long long
 10 #define pb push_back
 11 #define fi first
 12 #define se second
 13 
 14 const int N = 1010;
 15 const int M = 1e5;
 16 const int INF = 1e9;
 17 struct node{
 18     int x, d;
 19     bool friend operator<(const node& a, const node& b){
 20         return a.d > b.d;
 21     }
 22 };
 23 struct edge{
 24     int to, nxt, flow;
 25 }e[M << 1];
 26 vector<pair<int, int> > E[2][N];
 27 int dis[2][N];
 28 priority_queue<node > que; //最短路
 29 queue<int > Q;//网络流分层
 30 int d[N];//层级
 31 int n, m, A, B;
 32 int head[N], cur[N], vis[N], id[N]; //链式,当前弧优化,...,编号记录
 33 int tot, cnt;
 34 
 35 void dijkstra(int now, int pos)
 36 {
 37     for(int i = 0; i <= n; ++i) dis[pos][i] = INF;
 38     while(!que.empty()) que.pop();
 39     dis[pos][now] = 0;
 40     que.push({now, 0});
 41 
 42     while(!que.empty()){
 43         int u = que.top().x;
 44         que.pop();
 45 
 46         for(auto e : E[pos][u]){
 47             int v = e.fi;
 48             int w = e.se;
 49 
 50             if(dis[pos][v] > dis[pos][u] + w){
 51                 dis[pos][v] = dis[pos][u] + w;
 52                 que.push({v, dis[pos][v]});
 53             }
 54         }
 55     }
 56     
 57 }
 58 
 59 inline void add(int u, int v)
 60 {
 61     e[tot].to = v; e[tot].flow = 1;
 62     e[tot].nxt = head[u]; head[u] = tot++;
 63     e[tot].to = u; e[tot].flow = 0;
 64     e[tot].nxt = head[v]; head[v] = tot++;
 65 }
 66 
 67 void build()
 68 {
 69     for(int i = 0; i <= n; ++i) head[i] = -1; tot = 0;
 70     for(int x = 1; x <= n; ++x){
 71         for(auto e : E[0][x]){
 72             int y = e.fi;
 73             int w = e.se;
 74             if(dis[0][x] + dis[1][y] + w == dis[0][B] || dis[0][y] + dis[1][x] + w == dis[0][B]){
 75                 if(!vis[x]) id[cnt++] = x, vis[x] = 1;
 76                 if(!vis[y]) id[cnt++] = y, vis[y] = 1;
 77                 add(x, y);
 78             }
 79         }   
 80     }
 81 }
 82 
 83 bool bfs()
 84 {
 85     while(!Q.empty()) que.pop();
 86     for(int i = 0; i < cnt; ++i) {
 87         d[id[i]] = 0;
 88     }
 89     d[A] = 1;
 90     Q.push(A);
 91 
 92     while(!Q.empty()){
 93         int now = Q.front();
 94 
 95         Q.pop();
 96 
 97         for(int o = head[now]; ~o; o = e[o].nxt){
 98             int to = e[o].to;
 99             int flow = e[o].flow;
100 
101             if(flow && !d[to]){
102                 d[to] = d[now] + 1;
103                 Q.push(to);
104             }
105         }
106     }
107 
108     if(!d[B]) return false;
109     else return true;
110 }
111 
112 int dfs(int now, int pre_flow){
113     if(now == B) return pre_flow;
114     int sum = 0;
115     for(int& o = cur[now]; ~o; o = e[o].nxt){
116         int to = e[o].to;
117         int flow = e[o].flow;
118 
119         if(flow && d[to] == d[now] + 1){
120             int tmp = dfs(to, min(pre_flow - sum, flow));
121             if(tmp == 0) continue;
122             e[o].flow -= tmp;
123             e[o ^ 1].flow += tmp;
124             sum += tmp;
125             if(sum == pre_flow) return sum;
126         }
127     }
128     return sum;
129 }
130 
131 void dinic()
132 {
133     int mf = 0;
134     while(bfs()){
135         for(int i = 0; i < cnt; ++i) cur[id[i]] = head[id[i]];
136         mf += dfs(A, INF);
137     }
138 
139     printf("%d\n", mf);
140 }
141 
142 void init(){
143     for(int i = 0; i <= n; ++i){
144         E[0][i].clear();
145         E[1][i].clear();
146     }
147     for(int i = 0; i < cnt; ++i) vis[id[i]] = 0;
148     cnt = 0;
149 }
150 
151 void solve()
152 {
153     int T;
154     scanf("%d", &T);
155 
156     while(T--){
157         scanf("%d%d", &n, &m);
158         
159         init();
160 
161         int u, v, w;
162         for(int i = 0; i < m; ++i){
163             scanf("%d%d%d", &u, &v, &w);
164             if(u == v) continue;
165             E[0][u].pb(make_pair(v, w));
166             E[1][v].pb(make_pair(u, w));
167         }
168         scanf("%d%d", &A, &B);
169         dijkstra(A, 0);
170         dijkstra(B, 1);
171 
172         build();
173         dinic(); 
174     }
175 }
176 
177 int main()
178 {
179 
180     solve();
181 
182     return 0;
183 }

 

Marriage Match IV HDU - 3416

标签:bool   pair   long   vector   lin   scan   其他   main   pre   

原文地址:https://www.cnblogs.com/SSummerZzz/p/13220282.html

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