hdu 3416 Marriage Match IV (最短路+最大流)
2015-08-13 10:02
274 查看
hdu 3416 Marriage Match IV
DescriptionDo not sincere non-interference。
Like that show, now starvae also take part in a show, but it take place between city A and B. Starvae is in city A and girls are in city B. Every time starvae can get to city B and make a data with a girl he likes. But there are two problems with it, one is starvae must get to B within least time, it’s said that he must take a shortest path. Other is no road can be taken more than once. While the city starvae passed away can been taken more than once.
So, under a good RP, starvae may have many chances to get to city B. But he don’t know how many chances at most he can make a data with the girl he likes . Could you help starvae?
Input
The first line is an integer T indicating the case number.(1<=T<=65)
For each case,there are two integer n and m in the first line ( 2<=n<=1000, 0<=m<=100000 ) ,n is the number of the city and m is the number of the roads.
Then follows m line ,each line have three integers a,b,c,(1<=a,b<=n,0
题目大意:有n个城市m条路,从城市A到城市B的最短路径有几条。
解题思路:先正向反向求最短路,获得起点到每点的最短距离d1[], 终点到每点的最短距离d2[],最短路Min。然后遍历每一条边,当d1[edges.from]+edges.dis+d2[edges.to]==Min时,将该边加入最大流的图中,容量为1,建完图后,以A为源点,B为汇点跑最大流即可。
[code]#include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <cstdlib> #include <queue> using namespace std; const int INF = 0x3f3f3f3f; const int N = 2005; const int M = 200005; typedef long long ll; int n, m, s, t, Min; struct Edge{ int from,to; ll dist; }; struct HeapNode{ int d,u; bool operator < (const HeapNode& rhs) const{ return d > rhs.d; } }; struct Dinic{ int ec, head , first , que , lev ; int Next[M], to[M], v[M]; void init() { ec = 0; memset(first, -1, sizeof(first)); } void addEdge(int a,int b,int c) { to[ec] = b; v[ec] = c; Next[ec] = first[a]; first[a] = ec++; to[ec] = a; v[ec] = 0; Next[ec] = first[b]; first[b] = ec++; } int BFS() { int kid, now, f = 0, r = 1, i; memset(lev, 0, sizeof(lev)); que[0] = s, lev[s] = 1; while (f < r) { now = que[f++]; for (i = first[now]; i != -1; i = Next[i]) { kid = to[i]; if (!lev[kid] && v[i]) { lev[kid] = lev[now] + 1; if (kid == t) return 1; que[r++] = kid; } } } return 0; } int DFS(int now, int sum) { int kid, flow, rt = 0; if (now == t) return sum; for (int i = head[now]; i != -1 && rt < sum; i = Next[i]) { head[now] = i; kid = to[i]; if (lev[kid] == lev[now] + 1 && v[i]) { flow = DFS(kid, min(sum - rt, v[i])); if (flow) { v[i] -= flow; v[i^1] += flow; rt += flow; } else lev[kid] = -1; } } return rt; } int dinic() { int ans = 0; while (BFS()) { for (int i = 0; i <= n; i++) { head[i] = first[i]; } ans += DFS(s, INF); } return ans; } }din; struct Dijkstra{ int n,m; //点数和边数 vector<Edge> edges; //边列表 vector<int> G[M]; //每个结点出发的边编号(从0开始编号) bool done ; //是否已永久标号 int d ; //s到各个点的距离 ll L; void init(int n) { this->n = n; for(int i = 0; i <= m * 2; i++) G[i].clear();//清空邻接表 edges.clear();//清空边表 } void addEdge(int from, int to, ll dist) { //如果是无向图,每条无向边需调用两次AddEdge edges.push_back((Edge){from, to, dist}); m = edges.size(); G[from].push_back(m - 1); } void dijkstra(int s) {//求s到所有点的距离 priority_queue<HeapNode> Q; for(int i = 0; i <= n; i++) d[i] = INF; d[s] = 0; memset(done, 0, sizeof(done)); Q.push((HeapNode){0, s}); while(!Q.empty()){ HeapNode x = Q.top(); Q.pop(); int u = x.u; if(done[u]) continue; done[u] = true; for(int i = 0; i < G[u].size(); i++){ Edge& e = edges[G[u][i]]; if(d[e.to] > d[u] + e.dist){ d[e.to] = d[u] + e.dist; Q.push((HeapNode){d[e.to], e.to}); } } } } }dij, dij2; void input() { int u, v, d; scanf("%d %d", &n, &m); dij.init(n); dij2.init(n); for (int i = 0; i < m; i++) { scanf("%d %d %d", &u, &v, &d); dij.addEdge(u, v, d); dij2.addEdge(v, u, d); } scanf("%d %d", &s, &t); dij.dijkstra(s); dij2.dijkstra(t); Min = dij.d[t]; } void solve() { din.init(); for (int i = 0; i < m; i++) { if (dij.d[dij.edges[i].from] + dij2.d[dij.edges[i].to] + dij.edges[i].dist == Min) { din.addEdge(dij.edges[i].from, dij.edges[i].to, 1); } } printf("%d\n", din.dinic()); } int main() { int T; scanf("%d", &T); while (T--) { input(); solve(); } return 0; }
相关文章推荐
- java 导出word乱码问题,99%解决问题
- C语言:内存的分配与管理
- (转载)数据库出现ORA-00283/ORA-01610的问题
- C/C++之类型强制转化
- [POI2007][BZOJ1103] 大都市meg|dfs序|树状数组
- JAVA 设计模式-单例模式
- Gson 转换树型结构的实例
- android内部存储外部存储以及assets文件的操作一些操作
- phpstrom快捷键
- 小白学开发(iOS)OC_ 使用继承来扩充类(2015-08-07)
- Redis与Memcached的比较
- libjpeg交叉编译
- ssh远程登录到另一台机器命令
- python中函数接收多余参数
- 音频处理的技术指标
- C/C++之Memcpy and memmove
- 【转】HBase中的时间维度
- junit常用注解详细说明
- HDU 5375
- 深入学习JavaScript中的原型prototype