Q - Marriage Match IV

Do 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<c<=1000)it means there is a road from a to b and

it’s distance is c, while there may have no road from b to a. There

may have a road from a to a,but you can ignore it. If there are two

roads from a to b, they are different.

At last is a line with two integer A and B(1<=A,B<=N,A!=B), means the

number of city A and city B. There may be some blank line between

each case. Output Output a line with a integer, means the chances

starvae can get at most. Sample Input

3
7 8
1 2 1
1 3 1
2 4 1
3 4 1
4 5 1
4 6 1
5 7 1
6 7 1
1 7 6 7
1 2 1
2 3 1
1 3 3
3 4 1
3 5 1
4 6 1
5 6 1
1 6 2 2
1 2 1
1 2 2
1 2
Sample Output
2
1
1
  • 题意:一个人 从 城市 A 到 B 的最短路径有几条,这里特别需要注意:每条路经只能走一次,走过之后就不能再走了,而且只能走最短的路径
  • 思路:把不是最组成短路径(这里 最短路可能有多条)点边剔除掉,把剩余的边重新建图,边权设置为1,跑一遍最大流。

    那么我们我现在要解决的问题是怎么判断某一条边 是组成最短路径的边呢?

    我们先做一些假设:
  1. 假设要判断的边是 (u ,v),其长度是 w(u,v),假设图的 源点为 s 、汇点为 e。
  2. 正向跑最短路 的到的从 s 到其他点的最短距离存放在 dis1[ ] 数组中,

    dis[ u ] 为s到u的最短距离;
  3. 逆向跑最短路(但是带到权值还是 正向的权值) 的到的从 e 到其他点的最短距离存放在 dis2[ ] 数组中,dis[ v ] 为u到e (注意这个方向是u到v)的最短距离
  • 最后我们只要在遍历所给的每一条边时:

    如果 dis1[ u ] + w(u, v) + dis2[ v ] = dis1[ e ] 成立。那么我们就可判断这条边就是组成最短的路径的边。

    最后把这些 边新建图跑最大流,就能得出 路径方案数了。
  • 其实剩下的我们还要考虑一下:为什么最大流跑出来的就是我们所要的 答案?????????

题解(Spfa + ISAP)

#include<iostream>
#include<queue>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std; #define INF 0x3f3f3f3f
const int maxn = 10005;
const int maxm = 200005; struct Edge
{
int v,w,next;
} edge1[maxm], edge2[maxm], edge[maxm];
int n,m,s,e;
int head1[maxn], head2[maxn], head[maxn];
int dis1[maxn], dis2[maxn];
int use[maxn]; int k1,k2,k;
void Add(int u, int v, int w, int head[], int & k, Edge edge[])
{
edge[++ k] = (Edge){ v, w, head[u]}; head[u] = k;
} void Spfa(int s, int dis[], int head[], Edge edge[])
{
for(int i = 1; i <= n; i ++)
dis[i] = INF,use[i] = 0;
dis[s] = 0;
queue<int> q;
q.push(s);
int u,v,w;
while(! q.empty())
{
u = q.front();
q.pop();
use[u] = 0; for(int i = head[u]; i != -1; i = edge[i].next)
{
v = edge[i].v;
w = edge[i].w;
if(dis[v] > dis[u] + w)
{
dis[v] = dis[u] + w;
if(! use[v])
{
q.push(v);
use[v] = 1;
}
}
}
}
} int deep[maxn], num[maxn];
int cur[maxn], last[maxm]; void bfs(int e)
{
for(int i = 0; i <= n; i ++)
deep[i] = n, cur[i] = head[i], use[i] = 0;
deep[e] = 0;
queue<int> q;
q.push(e);
int u, v;
while(! q.empty())
{
u = q.front(); q.pop();
// use[u] = 0; for(int i = head[u]; i != -1; i = edge[i].next)
{
v = edge[i].v;
if(edge[i^1].w && deep[v] == n) //正图 边存在 且 v这个节点没有被求过
{
deep[v] = deep[u] + 1;
q.push(v);
// if(! use[v])
// {
// q.push(v);
// use[v] = 1;
// }
}
}
}
} int Add_flow(int s, int e)
{
int ans = INF;
int now = e;
while(now != s)
{
ans = min(ans, edge[last[now]].w);
now = edge[last[now]^1].v;
}
now = e;
while(now != s)
{
edge[last[now]].w -= ans;
edge[last[now]^1].w += ans;
now = edge[last[now]^1].v;
}
return ans;
} int isap(int s, int e)
{
int now = s; //从起点开始进行操作
bfs(e); //先找出来一条边 被操作的增光路
for(int i = 1; i <= n; i ++) num[deep[i]] ++;
int mx_flw = 0;
while(deep[s] < n)
{
if(now == e) //如果到达汇点直接增广,重新回到源点进行下一轮增广
{
mx_flw += Add_flow(s, e);
now = s;
}
bool has_find = 0;
for(int i = cur[now]; i != -1; i = edge[i].next)
{
if(edge[i].w && deep[now] == deep[edge[i].v] + 1)
{
has_find = 1; //做标记已经找到一种可行路径
cur[now] = i; //优化当前弧
now = edge[i].v;
last[edge[i].v] = i;
break;
}
} if(! has_find)
{
int minn = n - 1;
for(int i = head[now]; i != -1; i = edge[i].next)
if(edge[i].w)
minn = min(minn, deep[edge[i].v]);
if( (-- num[deep[now]]) == 0) break; //gap 优化出现了断层
num[deep[now] = minn + 1] ++;
cur[now] = head[now];
if(now != s)
now = edge[last[now]^1].v;
}
}
return mx_flw;
} void init()
{
k1 = 0; k2 = 0; k = -1;
for(int i = 0; i <= n; i ++)
head1[i] = -1, head2[i] = -1, head[i] = -1; memset(num, 0, sizeof(num));
} int main()
{
//freopen("T.txt","r",stdin);
int t;
scanf("%d", &t);
while(t --)
{
scanf("%d %d", &n, &m);
init();
int u, v, w;
for(int i = 1; i <= m; i ++)
{
scanf("%d %d %d", &u, &v, &w);
Add(u, v, w, head1, k1, edge1);
Add(v, u, w, head2, k2, edge2);
}
scanf("%d %d", &s, &e);
Spfa(s, dis1, head1, edge1);
Spfa(e, dis2, head2, edge2); //遍历图中所有的边 去找组成所有最短了的边都有哪些
for(int i = 1; i <= m; i ++)
{
u = edge2[i].v;
v = edge1[i].v;
w = edge1[i].w;
if(dis1[u] + w + dis2[v] == dis1[e])
{
Add(u, v, 1, head, k, edge);
Add(v, u, 0, head, k, edge);
}
}
printf("%d\n", isap(s, e));
} reurn 0;
}

Q - Marriage Match IV (非重复最短路 + Spfa + 网络最大流Isap)的更多相关文章

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

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

  2. P3376 【模板】网络最大流——————Q - Marriage Match IV(最短路&最大流)

    第一道题是模板题,下面主要是两种模板,但都用的是Dinic算法(第二个题也是) 第一题: 题意就不需要讲了,直接上代码: vector代码: 1 //invalid types 'int[int]' ...

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

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

  4. Marriage Match IV(最短路+网络流)

    Marriage Match IV http://acm.hdu.edu.cn/showproblem.php?pid=3416 Time Limit: 2000/1000 MS (Java/Othe ...

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

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

  6. HDU3605:Marriage Match IV

    Marriage Match IV Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others ...

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

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

  8. HDU 3416 Marriage Match IV(ISAP+最短路)题解

    题意:从A走到B,有最短路,问这样不重复的最短路有几条 思路:先来讲选有效边,我们从start和end各跑一次最短路,得到dis1和dis2数组,如果dis1[u] + dis2[v] + cost[ ...

  9. SPFA+Dinic HDOJ 3416 Marriage Match IV

    题目传送门 题意:求A到B不同最短路的条数(即边不能重复走, 点可以多次走) 分析:先从A跑最短路,再从B跑最短路,如果d(A -> u) + w (u, v) + d (B -> v) ...

随机推荐

  1. 关于 InnoDB 锁的超全总结

    有点全的 InnoDB 锁 几个月之前,开始深入学习 MySQL .说起数据库,并发控制是其中很重要的一部分.于是,就这样开起了 MySQL 锁的学习,随着学习的深入,发现想要更好的理解锁,需要了解 ...

  2. adb模拟按键与输入

    在 adb shell 里有个很实用的命令叫 input,通过它可以做一些有趣的事情. input 命令的完整 help 信息如下: Usage: input [<source>] < ...

  3. C语言程序设计(三) 简单的算术运算和表达式

    第三章 简单的算术运算和表达式 算数运算符:一元.二元.三元(条件运算符) 1/2是整型除法,1.0/2是浮点数除法 求余运算(%)限定参与运算的两个操作数必须为整数,不能对两个实型数据进行求余运算 ...

  4. Python离线项目迁移部署

    最近遇到了一个场景:需要将Python项目文件打包到无法联网的主机上部署执行,本篇文章记录针对于该场景的处理方案. 说明: 源主机(可联网):安装了Python3和pip3 目标主机(无法联网):需安 ...

  5. 【Python】2.17学习笔记 移位运算符,逻辑运算符

    移位运算符 左移运算符 \(<<\),将对应的二进制数末尾补一颗零,高位自然溢出(遁入虚无 print( 5 << 2 ) 把\(5\)的二进制数左移两位 即把\(101\)变 ...

  6. ngzorro draw 第一次打开 ERROR TypeError: Cannot read property 'overlayElement' of undefined

    at NzDrawerComponent.push../node_modules/ng-zorro-antd/fesm5/ng-zorro-antd.js.NzDrawerComponent.trap ...

  7. 【开发工具 docker】值得学习的应用容器引擎docker安装

    概述: Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源. Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级.可移植的容器中,然后发布到任何 ...

  8. Untargeted lipidomics reveals specific lipid abnormality in nonfunctioning human pituitary adenomas 非靶向脂质组学揭示非功能人类脑垂体瘤中的特异性脂质 (解读人:胡丹丹)

    文献名:Untargeted lipidomics reveals specific lipid abnormality in nonfunctioning human pituitary adeno ...

  9. kerberos系列之hive认证配置

    大数据安全系列之hive的kerberos认证配置,其它系列链接如下 https://www.cnblogs.com/bainianminguo/p/12548076.html-----------安 ...

  10. 李宏毅老师机器学习课程笔记_ML Lecture 0-1: Introduction of Machine Learning

    引言: 最近开始学习"机器学习",早就听说祖国宝岛的李宏毅老师的大名,一直没有时间看他的系列课程.今天听了一课,感觉非常棒,通俗易懂,而又能够抓住重点,中间还能加上一些很有趣的例子 ...