hdu3416 Marriage Match IV 最短路+ 最大流
此题的大意:给定一幅有向图,求起点到终点(都是固定的)的不同的最短路有多少条。不同的最短路是说不能有相同的边,顶点可以重复。并且图含有平行边。
看了题以后,就想到暴力,但是暴力往往是不可取的。(暴力的最坏情况下的时间复杂度是O(n^3))。我说的暴力是求一次最短路以后,把最短路上的边全部去掉(权值设为INF)。
最短路可以有很多条,但是最短路的值只有一个。根据这个,我们可以判断某条边是否在最短路上。
建图(单向边),求最短路,起点就是输入的起点。枚举每一条边,如果满足dist[i]+Map[i][j]==dist[j],就建立一条权值为i,j之间长度等于最短边的边数。
我的做法是在建正向图的时候,用数组en[][]记录两点之间的长度等于最短边的边数。
看上去代码蛮长的,其实就2个模版,main()才是需要自己去写的。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = , M=, INF=;
int dist[N], Map[N][N], pre[N],en[N][N];
bool p[N];
void Dijkstra(int s,int n)
{
int i,j,k, MIN;
for(i=; i<=n; i++) //初始化
{
p[i]=;
if(i!=s)
{
dist[i]= Map[s][i];
pre[i]=s;
}
}
dist[s]=;
p[s]=;
for(i=; i<n; i++) //循环n-1次
{
MIN=INF;
k=;
for(j=; j<=n; j++)
{
if(!p[j]&&dist[j]<MIN)
{
MIN= dist[j];
k=j;
}
}
if(!k) return ;//没有点可以扩展
p[k]=; //将k从Vb中除去,加入Va
for(j=; j<=n; j++)
{
if(!p[j]&&Map[k][j]!=INF&&dist[j]>dist[k]+Map[k][j])
{
dist[j]= dist[k] + Map[k][j];
pre[j]=k;
}
}
}
}
struct node
{
int to,next,w;
}edge[M];
int head[N],numh[N],h[N],cure[N];
int ans,tot;
void SAP(int s, int e,int n)
{
int flow,u,tmp,neck,i;
ans=;
for(i=;i<=n;i++)
cure[i]=head[i];
numh[]=n;
u=s;
while(h[s]<n)
{
if(u==e)
{
flow =INF;
for(i=s;i!=e;i=edge[cure[i]].to)
{
if(flow>edge[cure[i]].w)
{
neck=i;
flow =edge[cure[i]].w;
}
}
for(i=s;i!=e;i=edge[cure[i]].to)
{
tmp=cure[i];
edge[tmp].w-=flow;
edge[tmp^].w+=flow;
}
ans+=flow;
u=neck;
}
for(i=cure[u];i!=-;i=edge[i].next)
if(edge[i].w && h[u]==h[edge[i].to]+) break;
if(i!=-) {cure[u]=i;pre[edge[i].to]=u;u=edge[i].to;}
else
{
if(==--numh[h[u]]) break; //GAP优化
cure[u]=head[u];
for(tmp=n,i=head[u];i!=-;i=edge[i].next)
if(edge[i].w) tmp=min(tmp, h[edge[i].to]);
h[u]=tmp+;
++numh[h[u]];
if(u!=s) u=pre[u];
}
}
}
void init()
{
tot=;
memset(head,-,sizeof(head));
memset(pre,-,sizeof(pre));
memset(h,,sizeof(h));
memset(numh,,sizeof(numh)); }
void addedge(int i,int j,int w)
{
edge[tot].to=j;edge[tot].w=w;edge[tot].next=head[i];head[i]=tot++;
edge[tot].to=i;edge[tot].w=;edge[tot].next=head[j];head[j]=tot++;
}
int main()
{
//freopen("test.txt","r",stdin);
int n,m,i,j,k,s,e,cas;
scanf("%d",&cas);
while(cas--)
{
scanf("%d%d",&n,&m);
for(i=;i<=n;i++)
for(j=;j<=n;j++)
{
Map[i][j]=INF;
en[i][j]=;
}
while(m--)
{
scanf("%d%d%d",&i,&j,&k);
if(i==j) continue;
if(Map[i][j]>k) {Map[i][j]=k, en[i][j]=;}
else if (Map[i][j]==k) {en[i][j]++;}
}
scanf("%d%d",&s,&e);
Dijkstra(s,n);
init();
for(i=;i<=n;i++)
{
for(j=;j<=n;j++)
{
if(Map[i][j]!=INF)
{
if(dist[i]+Map[i][j]==dist[j])
addedge(i,j,en[i][j]);
}
}
}
SAP(s,e,n);
printf("%d\n",ans);
}
return ;
}
hdu3416 Marriage Match IV 最短路+ 最大流的更多相关文章
- HDU-3416 Marriage Match IV 最短路+最大流 找各最短路的所有边
题目链接:https://cn.vjudge.net/problem/HDU-3416 题意 给一个图,求AB间最短路的条数(每一条最短路没有重边.可有重复节点) 思路 首先把全部最短路的边找出来,再 ...
- HDU3416 Marriage Match IV —— 最短路径 + 最大流
题目链接:https://vjudge.net/problem/HDU-3416 Marriage Match IV Time Limit: 2000/1000 MS (Java/Others) ...
- Marriage Match IV(最短路+网络流)
Marriage Match IV http://acm.hdu.edu.cn/showproblem.php?pid=3416 Time Limit: 2000/1000 MS (Java/Othe ...
- hdu3416 Marriage Match IV【最短路+最大流】
转载请注明出处,谢谢:http://www.cnblogs.com/KirisameMarisa/p/4297581.html ---by 墨染之樱花 题目链接:http://acm.hdu.ed ...
- hdu3416 Marriage Match IV(最短路+网络流)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3416 题意: 给出含n个点.m条有向边的图,每条边只能走一次,给出起点和终点,求起点到终点的最短路径有 ...
- HDU 3416 Marriage Match IV (最短路建图+最大流)
(点击此处查看原题) 题目分析 题意:给出一个有n个结点,m条单向边的有向图,问从源点s到汇点t的不重合的最短路有多少条,所谓不重复,意思是任意两条最短路径都不共用一条边,而且任意两点之间的边只会用一 ...
- HDU 3416 Marriage Match IV (Dijkstra+最大流)
题意:N个点M条边的有向图,给定起点S和终点T,求每条边都不重复的S-->T的最短路有多少条. 分析:首先第一步需要找出所有可能最短路上的边.怎么高效地求出呢?可以这样:先对起点S,跑出最短路: ...
- hdu3461Marriage Match IV 最短路+最大流
//给一个图.给定起点和终点,仅仅能走图上的最短路 //问最多有多少种走的方法.每条路仅仅能走一次 //仅仅要将在最短路上的全部边的权值改为1.求一个最大流即可 #include<cstdio& ...
- HDU 3416 Marriage Match IV (最短路径&&最大流)
/*题意: 有 n 个城市,知道了起点和终点,有 m 条有向边,问从起点到终点的最短路一共有多少条.这是一个有向图,建边的时候要注意!!解题思路:这题的关键就是找到哪些边可以构成最短路,其实之前做最短 ...
随机推荐
- js对比for、forEach、map遍历数组速度
function a() { var arr = new Array(1000000); for(var i = 0; i < arr.length;i ++) { arr[i] = i; } ...
- Ubuntu Server下docker实战 01: 安装docker
本系列文章主旨在于使用docker来搭建实际可用的基础服务,具体到每一步的操作和设置. 关于docker的原理.前世今生的内容,园子里已经有太多的文章了,此处就不再赘述. 要使用docker,当然第一 ...
- Java基础学习总结(66)——配置管理库typesafe.config教程
Typesafe的Config库,纯Java写成.零外部依赖.代码精简.功能灵活.API友好.支持Java properties.JSON.JSON超集格式HOCON以及环境变量.它也是Akka的配置 ...
- MySQL主要命令(4)
显示数据, 给列区别名: select coL_name as 别名 from table_name;
- 洛谷 P2587 BZOJ 1034 [ZJOI2008]泡泡堂
题目描述 //不知道为什么BZOJ和洛谷都没有这幅图了,大牛们几年前的博客上都有这幅图的,把它贴上来吧 第XXXX届NOI期间,为了加强各省选手之间的交流,组委会决定组织一场省际电子竞技大赛,每一个省 ...
- Sublime Text 3常用插件—Emmet
原文链接:http://www.cnblogs.com/easy-blue/p/6617852.html 摘要: 安装请看上一篇Sublime Text—安装,和sublime自带快捷键一起用,写ht ...
- SQL优化(SQL TUNING)之10分钟完毕亿级数据量性能优化(SQL调优)
前几天.一个用户研发QQ找我,例如以下: 自由的海豚. 16:12:01 岛主,我的一条SQL查不出来结果,能帮我看看不? 兰花岛主 16:12:10 多久不出结果? 自由的海豚 16:12:17 多 ...
- iOS 8 中 UIAlertView 和 UIActionSheet 河里去了?
iOS 8 中 UIAlertView 和 UIActionSheet 河里去了? 太阳火神的漂亮人生 (http://blog.csdn.net/opengl_es) 本文遵循"署名-非商 ...
- Codeforces Round #FF (Div. 2) D. DZY Loves Modification 贪心+优先队列
链接:http://codeforces.com/problemset/problem/447/D 题意:一个n*m的矩阵.能够进行k次操作,每次操作室对某一行或某一列的的数都减p,获得的得分是这一行 ...
- Object对象具体解释(二)之clone
clone方法会返回该实例对象的一个副本,通常情况下x.clone() != x || x.clone().getClass() == x.getClass() || x.clone().equals ...