HDU 3416 Marriage Match IV (最短路径&&最大流)
/*
题意: 有 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 (最短路径&&最大流)的更多相关文章
- HDU 3416 Marriage Match IV (最短路径,网络流,最大流)
HDU 3416 Marriage Match IV (最短路径,网络流,最大流) Description Do not sincere non-interference. Like that sho ...
- hdu 3416 Marriage Match IV (最短路+最大流)
hdu 3416 Marriage Match IV Description Do not sincere non-interference. Like that show, now starvae ...
- HDU 3416 Marriage Match IV (求最短路的条数,最大流)
Marriage Match IV 题目链接: http://acm.hust.edu.cn/vjudge/contest/122685#problem/Q Description Do not si ...
- HDU3416 Marriage Match IV —— 最短路径 + 最大流
题目链接:https://vjudge.net/problem/HDU-3416 Marriage Match IV Time Limit: 2000/1000 MS (Java/Others) ...
- HDU 3416 Marriage Match IV 【最短路】(记录路径)+【最大流】
<题目链接> 题目大意: 给你一张图,问你其中没有边重合的最短路径有多少条. 解题分析: 建图的时候记得存一下链式后向边,方便寻找最短路径,然后用Dijkstra或者SPFA跑一遍最短路, ...
- HDU 3416 Marriage Match IV (最短路建图+最大流)
(点击此处查看原题) 题目分析 题意:给出一个有n个结点,m条单向边的有向图,问从源点s到汇点t的不重合的最短路有多少条,所谓不重复,意思是任意两条最短路径都不共用一条边,而且任意两点之间的边只会用一 ...
- HDU 3416 Marriage Match IV (Dijkstra+最大流)
题意:N个点M条边的有向图,给定起点S和终点T,求每条边都不重复的S-->T的最短路有多少条. 分析:首先第一步需要找出所有可能最短路上的边.怎么高效地求出呢?可以这样:先对起点S,跑出最短路: ...
- hdu 3416 Marriage Match IV 【 最短路 最大流 】
求边不可重复的最短路条数 先从起点到终点用一次dijkstra,再从终点到起点用一次dijkstra,来判断一条边是否在最短路上 如果在,就将这条边的两个端点连起来,容量为1 再跑一下dinic(), ...
- HDU 3416 Marriage Match IV dij+dinic
题意:给你n个点,m条边的图(有向图,记住一定是有向图),给定起点和终点,问你从起点到终点有几条不同的最短路 分析:不同的最短路,即一条边也不能相同,然后刚开始我的想法是找到一条删一条,然后光荣TLE ...
随机推荐
- python基础语法1-变量
l Python基础语法1-变量
- MySQL查询优化之 index 索引的分类和使用
索引的分类 主键索引 (PRIMARY KEY) 唯一的标识符, 主键不可重复, 只能有一列作为主键 唯一索引 (Unique KEY) 避免重复的列出现, 唯一索引可以重复, 多个列都可以标识为唯一 ...
- maven打包项目
使用maven可以对项目进行很方便的管理,方便体现之一便是项目的打包发布变得方便,本文主要是讲一下maven打包时的一些命令和注意事项(皆是自己从应用中总结的理解,或有不对之处). maven项目打包 ...
- 史上最全postgreSQL体系结构(转)
原文链接:https://cloud.tencent.com/developer/article/1469101 墨墨导读:本文主要从日志文件.参数文件.控制文件.数据文件.redo日志(WAL).后 ...
- Windows安全加固
Windows安全加固 # 账户管理和认证授权 # 1.1 账户 # 默认账户安全 # 禁用Guest账户. 禁用或删除其他无用账户(建议先禁用账户三个月,待确认没有问题后删除.) 操作步骤 本地用户 ...
- [Usaco2016 Dec]Counting Haybales
原题链接https://www.lydsy.com/JudgeOnline/problem.php?id=4747 先将原数组排序,然后二分查找即可.时间复杂度\(O((N+Q)logN)\). #i ...
- STL_deque容器
一.deque简介 deque是"double-ended queue"的缩写,和vector一样都是STL的容器,deque是双端数组,而vector是单端的. deque在接口 ...
- file转化为binary对象发送给后台
具体代码如下: function filechange(e) { var file = $('#filed').get(0).files[0]; var fileSize = file.size, f ...
- (Sqlserver)sql求连续问题
题目一:create table etltable( name varchar(20) , seq int, money int); create table etltarget ( name var ...
- 用Jenkins构建Django持续集成环境
用Jenkins构建Django持续集成环境 - V2EX https://www.v2ex.com/t/32054