题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3416

题意:

给出含n个点、m条有向边的图,每条边只能走一次,给出起点和终点,求起点到终点的最短路径有多少条。

思路:

题目要求是最短路径,当然需要求出最短路,用Dijkstra就可以了,然后我们需要构造网络流的图。将能组成最短路的边加入图中,容量设为1,注意能组成最短路的边是满足dis[u] + edge[i].dist == dis[v] 的边,其中u是边的起点,v是边的终点,dis[]保存的是最短路。最后跑最大流即可。

代码如下:

 #include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<queue> using namespace std;
const int INF=0x3f3f3f3f;
const int maxn=;
const int maxm=;
struct node
{
int d,u;
friend bool operator<(node a,node b)
{
return a.d>b.d;
}
node(int dist,int point):d(dist),u(point){}
}; struct Edge1
{
int to,next;
int dist;
}edge1[maxm];
int head1[maxn],tot;
int pre[maxn],dis[maxn];
bool vis[maxm]; void init1()
{
memset(head1,-,sizeof(head1));
tot=;
} void addedge1(int u,int v,int d)
{
edge1[tot].to=v;
edge1[tot].dist=d;
edge1[tot].next=head1[u];
head1[u]=tot++;
} void Dijkstra(int s)
{
priority_queue<node> q;
memset(dis,0x3f,sizeof(dis));
memset(pre,-,sizeof(pre));
dis[s]=;
while(!q.empty())
q.pop();
node a(,s);
q.push(a);
while(!q.empty())
{
node x=q.top();
q.pop();
if(dis[x.u]<x.d)
continue;
for(int i=head1[x.u];i!=-;i=edge1[i].next)
{
int v=edge1[i].to;
if(dis[v]>dis[x.u]+edge1[i].dist)
{
dis[v]=dis[x.u]+edge1[i].dist;
pre[v]=x.u;
q.push(node(dis[v],v));
}
}
}
}
const int MAXN = ;
const int MAXM = ;
struct Temp
{
int u,v;
}temp[MAXM];
int cnt;
void dfs(int u)
{
for(int i=head1[u];i!=-;i=edge1[i].next)
{
int v=edge1[i].to;
if(dis[u]+edge1[i].dist==dis[v]&&(!vis[i]))
{
temp[cnt].u=u;
temp[cnt++].v=v;
vis[i]=true;
dfs(v);
}
}
} struct Edge2
{
int to, next, cap, flow;
}edge[MAXM];
int tol;
int head[MAXN];
void init()
{
tol = ;
memset(head, -, sizeof(head));
}
void addedge(int u, int v, int w, int rw=)
{
edge[tol].to = v; edge[tol].cap = w; edge[tol].flow = ;
edge[tol].next = head[u]; head[u] = tol++;
edge[tol].to = u; edge[tol].cap = rw; edge[tol].flow = ;
edge[tol].next = head[v]; head[v] = tol++;
}
int Q[MAXN];
int dep[MAXN], cur[MAXN], sta[MAXN];
bool bfs(int s, int t, int n)
{
int front = , tail = ;
memset(dep, -, sizeof(dep[])*(n+));
dep[s] = ;
Q[tail++] = s;
while(front < tail)
{
int u = Q[front++];
for(int i = head[u]; i != -; i = edge[i].next)
{
int v = edge[i].to;
if(edge[i].cap > edge[i].flow && dep[v] == -) {
dep[v] = dep[u] + ;
if(v == t) return true;
Q[tail++] = v;
}
}
}
return false;
}
int dinic(int s, int t, int n) {
int maxflow = ;
while(bfs(s, t, n)) {
for(int i = ; i < n; i++) cur[i] = head[i];
int u = s, tail = ;
while(cur[s] != -)
{
if(u == t)
{
int tp = INF;
for(int i = tail-; i >= ; i--)
tp = min(tp, edge[sta[i]].cap-edge[sta[i]].flow);
maxflow+=tp;
for(int i = tail-; i >= ; i--) {
edge[sta[i]].flow+=tp;
edge[sta[i]^].flow-=tp;
if(edge[sta[i]].cap-edge[sta[i]].flow==)
tail = i;
}
u = edge[sta[tail]^].to;
}
else
if(cur[u] != - && edge[cur[u]].cap > edge[cur[u]].flow && dep[u] + == dep[edge[cur[u]].to])
{
sta[tail++] = cur[u];
u = edge[cur[u]].to;
}
else
{
while(u != s && cur[u] == -)
u = edge[sta[--tail]^].to;
cur[u] = edge[cur[u]].next;
}
}
}
return maxflow;
}
int n,m,a,b; int main()
{
int t;
scanf("%d",&t);
while(t--)
{
init1();
scanf("%d%d",&n,&m);
for(int i=;i<=m;++i)
{
int u,v,c;
scanf("%d%d%d",&u,&v,&c);
if(u!=v)
addedge1(u,v,c);
}
scanf("%d%d",&a,&b);
Dijkstra(a);
memset(vis,false,sizeof(vis));
cnt=;
dfs(a);
init();
for(int i=;i<cnt;++i)
addedge(temp[i].u-,temp[i].v-,);
int ans=dinic(a-,b-,n);
cout<<ans<<endl;
}
return ;
}

hdu3416 Marriage Match IV(最短路+网络流)的更多相关文章

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

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

  2. HDU-3416 Marriage Match IV 最短路+最大流 找各最短路的所有边

    题目链接:https://cn.vjudge.net/problem/HDU-3416 题意 给一个图,求AB间最短路的条数(每一条最短路没有重边.可有重复节点) 思路 首先把全部最短路的边找出来,再 ...

  3. hdu3416 Marriage Match IV 最短路+ 最大流

    此题的大意:给定一幅有向图,求起点到终点(都是固定的)的不同的最短路有多少条.不同的最短路是说不能有相同的边,顶点可以重复.并且图含有平行边. 看了题以后,就想到暴力,但是暴力往往是不可取的.(暴力的 ...

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

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

  5. hdu3416 Marriage Match IV【最短路+最大流】

    转载请注明出处,谢谢:http://www.cnblogs.com/KirisameMarisa/p/4297581.html   ---by 墨染之樱花 题目链接:http://acm.hdu.ed ...

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

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

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

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

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

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

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

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

随机推荐

  1. nyoj_600:花儿朵朵(树状数组+坐标离散化)

    http://acm.nyist.net/JudgeOnline/problem.php?pid=600 只附代码好了 #include<bits/stdc++.h> using name ...

  2. eclipse连接hadoop问题

    1,首先可以测试:hafs dfsadmin -safemode leave2,如果出现下面的问题Error:Permission denied: user= ,access=READ_EXECUTE ...

  3. (转)TCP和UDP之间的区别

    TCP和UDP区别     TCP UDP 是否连接 面向连接 面向非连接 传输可靠性 可靠的 不可靠的 应用场合 传输大量的数据 少量数据 速度 慢 快    OSI 和 TCP/IP 模型在传输层 ...

  4. 《Unity3D-播放被打中的时候粒子的特效的代码》

    //思路:首先我们需要给这个敌人身上放置上被打中的时候的粒子效果的组件,然后在获取和初始化这个组件然后在播放这个组件.虽然这个过程很简单但是我们要让 组件随着敌人的移动的时候随时触发就必须将这个组件的 ...

  5. Redis-误操作尝试恢复

    如果不小心使用了flushall把全部数据清楚怎么办 127.0.0.1:6379> set site www.google.com OK 127.0.0.1:6379> set addr ...

  6. XML 入门 - XML 系统教程(1)

    XML (Extensible Markup Language)指可扩展标记语言. 组成 <?xml version="1.0" encoding="UTF-8&q ...

  7. 带你快速进入.net core的世界

    [申明]:本人.NET Core小白.Linux小白.MySql小白.nginx小白.而今天要说是让你精通Linux ... 的开机与关机.nginx安装与部署.Core的Hello World .. ...

  8. Java集合框架Collections【List/Set】

    1.基本介绍: 集合就是存放对象的,他比数组好的一点就是他一开始不清楚自己长度 容器一般是分为很多种的,很多的容器在一起然后进过断的抽象和抽取就成了一个体系,我们称之为集合框架 我们看体系首先是看顶层 ...

  9. kill 和killall----杀死进程

    1.根据进程ip查看进程名 Liunx中 通过进程名查找进程PID可以通过 pidof  [进程名] 来查找. 反过来 ,通过PID查找进程名则没有相关命令.但在linux根目录中,有一个/proc的 ...

  10. JSR-303 Bean Validation 介绍及 Spring MVC 服务端参数验证最佳实践

    任何时候,当要处理一个应用程序的业务逻辑,数据校验是你必须要考虑和面对的事情. 应用程序必须通过某种手段来确保输入参数在上下文来说是正确的. 分层的应用很多时候同样的数据验证逻辑会出现在不同的层,这样 ...