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

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

代码:

  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 }

HDU 3416 Marriage Match IV (最短路径&&最大流)的更多相关文章

  1. HDU 3416 Marriage Match IV (最短路径,网络流,最大流)

    HDU 3416 Marriage Match IV (最短路径,网络流,最大流) Description Do not sincere non-interference. Like that sho ...

  2. hdu 3416 Marriage Match IV (最短路+最大流)

    hdu 3416 Marriage Match IV Description Do not sincere non-interference. Like that show, now starvae ...

  3. HDU 3416 Marriage Match IV (求最短路的条数,最大流)

    Marriage Match IV 题目链接: http://acm.hust.edu.cn/vjudge/contest/122685#problem/Q Description Do not si ...

  4. HDU3416 Marriage Match IV —— 最短路径 + 最大流

    题目链接:https://vjudge.net/problem/HDU-3416 Marriage Match IV Time Limit: 2000/1000 MS (Java/Others)    ...

  5. HDU 3416 Marriage Match IV 【最短路】(记录路径)+【最大流】

    <题目链接> 题目大意: 给你一张图,问你其中没有边重合的最短路径有多少条. 解题分析: 建图的时候记得存一下链式后向边,方便寻找最短路径,然后用Dijkstra或者SPFA跑一遍最短路, ...

  6. HDU 3416 Marriage Match IV (最短路建图+最大流)

    (点击此处查看原题) 题目分析 题意:给出一个有n个结点,m条单向边的有向图,问从源点s到汇点t的不重合的最短路有多少条,所谓不重复,意思是任意两条最短路径都不共用一条边,而且任意两点之间的边只会用一 ...

  7. HDU 3416 Marriage Match IV (Dijkstra+最大流)

    题意:N个点M条边的有向图,给定起点S和终点T,求每条边都不重复的S-->T的最短路有多少条. 分析:首先第一步需要找出所有可能最短路上的边.怎么高效地求出呢?可以这样:先对起点S,跑出最短路: ...

  8. hdu 3416 Marriage Match IV 【 最短路 最大流 】

    求边不可重复的最短路条数 先从起点到终点用一次dijkstra,再从终点到起点用一次dijkstra,来判断一条边是否在最短路上 如果在,就将这条边的两个端点连起来,容量为1 再跑一下dinic(), ...

  9. HDU 3416 Marriage Match IV dij+dinic

    题意:给你n个点,m条边的图(有向图,记住一定是有向图),给定起点和终点,问你从起点到终点有几条不同的最短路 分析:不同的最短路,即一条边也不能相同,然后刚开始我的想法是找到一条删一条,然后光荣TLE ...

随机推荐

  1. Linux tar压缩和解压

    经常会忘记 tar 压缩和解压命令的使用,故记下来. 1. 打包压缩 tar -zcvf pack.tar.gz pack/ #打包压缩为一个.gz格式的压缩包 tar -jcvf pack.tar. ...

  2. 动态sql语句、逆向工程(generator)、分页助手(pagehelper)

    1.动态sql语句 if if where 配合使用 <select id="selectByWhere" resultType="com.alibaba.wlq. ...

  3. uni-app开发经验分享十三:实现手机扫描二维码并跳转全过程

    最近使用 uni-app 开发 app ,需要实现一个调起手机摄像头扫描二维码功能,官网API文档给出了这样一个demo: // 允许从相机和相册扫码 uni.scanCode({ success: ...

  4. 在原生开发中控制HTML5视频!

    在原生开发中控制HTML5视频! PC端 视频如何自动播放! 在video标签中添加 autoplay + muted(静音属性!) 温馨提醒: video是一个块级元素! 但是唯一的缺陷就是视频没有 ...

  5. Linux系统设置 SSH 通过密钥登录

    我们一般使用 PuTTY 等 SSH 客户端来远程管理 Linux 服务器.但是,一般的密码方式登录,容易有密码被暴力破解的问题.所以,一般我们会将 SSH 的端口设置为默认的 22 以外的端口,或者 ...

  6. Property attribute.

    class property(object): """ Property attribute. fget function to be used for getting ...

  7. Nginx配置代理gRPC的方法

    Nginx配置代理gRPC的方法_nginx_脚本之家 https://www.jb51.net/article/137330.htm

  8. P6739 [BalticOI 2014 Day1] Three Friends 题解

    目录 写在前面 Solution 何为字符串哈希(可跳过): Code 写在前面 P6739 [BalticOI 2014 Day1] Three Friends 听说这题可以用比较暴力的做法过,比如 ...

  9. 题解 P1248 【加工生产调度】

    题目 某工厂收到了 n 个产品的订单,这 n 个产品分别在 A.B 两个车间加工,并且必须先在 A 车间加工后才可以到 B 车间加工. 某个产品 i 在 A.B 两车间加工的时间分别为 Ai,Bi 怎 ...

  10. Hive 使用总结

    1 带分区列的表更改列类型 常见的一个场景是Hive里面一个带分区的表,原来是int类型的字段,后来发现数据超过了int的最大值,要改成bigint.或者是bigint要改string或decimal ...