HDU 3416 Marriage Match IV (最短路径&&最大流)

/*
题意: 有 n 个城市,知道了起点和终点,有 m 条有向边,问从起点到终点的最短路一共有多少条。这是一个有向图,建边的时候要注意!!

解题思路:这题的关键就是找到哪些边可以构成最短路,其实之前做最短路的题目接触过很多,反向建一个图,求两边最短路,即从src到任一点的最短路dis1[]和从des到任一点的最短路dis2[],那么假设这条边是(u,v,w),如果dis1[u] + w + dis2[v] = dis1[des],说明这条边是构成最短路的边。找到这些边,就可以把边的容量设为1,跑一边最大流即可。
————————————————

 

代码:

HDU 3416 Marriage Match IV (最短路径&&最大流)
  1 #include<stdio.h>
  2 #include<algorithm>
  3 #include<string.h>
  4 #include<queue>
  5 using namespace std;
  6 const int maxn = 1005;
  7 const int inf = 0x3f3f3f3f;
  8 int t, u, v, w;
  9 struct node
 10 {
 11     int u, v, w, next;
 12 }edge[800005], e[100005];
 13 int head[maxn], dis[2][maxn], pre[2][maxn],level[maxn];
 14 bool vis[maxn];
 15 int n, m, st, ed, tot;
 16 void init()
 17 {
 18     tot = 0;
 19     memset(head, -1, sizeof(head));
 20     memset(pre, -1, sizeof(pre));
 21     return;
 22 }
 23 void addedge(int u, int v, int w)
 24 {
 25     edge[tot].v = v;
 26     edge[tot].w = w;
 27     edge[tot].next = head[u];
 28     head[u] = tot++;
 29     edge[tot].v = u;
 30     edge[tot].w = w;
 31     edge[tot].next = head[v];
 32     head[v] = tot++;
 33     return;
 34 }
 35 void addedge1(int u,int v,int w)
 36 {
 37     edge[tot].v = v;
 38     edge[tot].w = w;
 39     edge[tot].next = pre[0][u];
 40     pre[0][u] = tot++;
 41     return;
 42 }
 43 void addedge2(int u, int v, int w)
 44 {
 45     edge[tot].v = v;
 46     edge[tot].w = w;
 47     edge[tot].next = pre[1][u];
 48     pre[1][u] = tot++;
 49     return;
 50 }
 51 void spfa(int st, int ed, int idx)
 52 {
 53     queue<int>pq;
 54     memset(dis[idx], inf, sizeof(dis[idx]));
 55     memset(vis, false, sizeof(vis));
 56     dis[idx][st] = 0;
 57     pq.push(st);
 58     vis[st] = true;
 59     while (!pq.empty())
 60     {
 61         int u = pq.front();
 62         pq.pop();
 63         vis[u] = false;
 64         for (int i = pre[idx][u]; i != -1; i = edge[i].next)
 65         {
 66             int v = edge[i].v;
 67             if(dis[idx][v] > dis[idx][u] + edge[i].w)
 68             {
 69                 dis[idx][v] = dis[idx][u] + edge[i].w;
 70                 if (!vis[v])
 71                 {
 72                     pq.push(v);
 73                     vis[v] = true;
 74                 }
 75             }
 76         }
 77     }
 78 }
 79 void build()
 80 {
 81     for (int i = 1; i <= m; i++)
 82     {
 83         u = e[i].u;
 84         v = e[i].v;
 85         w = e[i].w;
 86         if (dis[0][u] + dis[1][v] + w == dis[0][ed])
 87         {
 88             addedge(u, v, 1);
 89         }
 90     }
 91 }
 92 int bfs(int st, int ed)
 93 {
 94     queue<int>q;
 95     memset(level, 0, sizeof(level));
 96     level[st] = 1;
 97     q.push(st);
 98     while (!q.empty())
 99     {
100         int u = q.front();
101         q.pop();
102         if (u == ed)
103         {
104             return 1;
105         }
106         for (int i = head[u]; i != -1; i = edge[i].next)
107         {
108             int v = edge[i].v;
109             int w = edge[i].w;
110             if (level[v] == 0 && w != 0)
111             {
112                 level[v] = level[u] + 1;
113                 q.push(v);
114             }
115         }
116     }
117     return -1;
118 }
119 int dfs(int st, int ed, int f)
120 {
121     if (st == ed)
122     {
123         return f;
124     }
125     int ret = 0;
126     for (int i = head[st]; i != -1; i = edge[i].next)
127     {
128         int v = edge[i].v;
129         int w = edge[i].w;
130         if (level[v] == level[st] + 1 && w != 0)
131         {
132             int MIN = min(f - ret, w);
133             w = dfs(v, ed, MIN);
134             if (w > 0)
135             {
136                 edge[i].w -= w;
137                 edge[i ^ 1].w += w;
138                 ret += w;
139                 if (ret == f)
140                 {
141                     return ret;
142                 }
143             }
144             else
145             {
146                 level[v] = -1;
147             }
148         }
149     }
150     return ret;
151 }
152 int dinic(int st,int ed)
153 {
154     int ans = 0;
155     while (bfs(st, ed) != -1)
156     {
157         ans += dfs(st, ed, inf);
158     }
159     return ans;
160 }
161 int main()
162 {
163     //freopen("C:/input.txt", "r", stdin);
164     scanf("%d", &t);
165     while (t--)
166     {
167         init();
168         scanf("%d%d", &n, &m);
169         for (int i = 1; i <= m; i++)
170         {
171             scanf("%d%d%d", &u, &v, &w);
172             e[i].u = u, e[i].v = v, e[i].w = w;
173             addedge1(u, v, w);
174             addedge2(v, u, w);
175         }
176         scanf("%d%d", &st, &ed);
177         spfa(st, ed, 0);
178         spfa(ed, st, 1);
179         build();
180         int maxflow = dinic(st, ed);
181         printf("%d\n", maxflow);
182     }
183     return 0;
184 }
View Code

 

上一篇:HDU-3081-Marriage Match 2(最大流, 二分答案, 并查集)


下一篇:N - Marriage Match II 网络流