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 条有向边,问从起点到终点的最短路一共有多少条.这是一个有向图,建边的时候要注意!!解题思路:这题的关键就是找到哪些边可以构成最短路,其实之前做最短 ...
随机推荐
- 【转载】深入理解Java的接口和抽象类
深入理解Java的接口和抽象类 对于面向对象编程来说,抽象是它的一大特征之一.在Java中,可以通过两种形式来体现OOP的抽象:接口和抽象类.这两者有太多相似的地方,又有太多不同的地方.很多人在初学的 ...
- eas之树
如何设置树的深度(即树总共有几级) // 设置树的深度为3,即树包括0.1.2三级结点 table.getTreeColumn().setDepth(3); 如何设置树的方向 树的方向包括两种:自上向 ...
- 解决windows文件在linux系统中显示乱码的问题
问题: 在Windows下用matlab写的代码(.m)到Linux(centos)下,注释的中文全是乱码. 原因: Windows下默认使用的是GB2312编码,Linux默认使用的是UTF-8. ...
- Git 基础教程 之 创建版本库
一,选择一个合适的地方,创建空目录,下面两种方法都可 ① 手动新建 ② 使用命令: mkdir pythonwork 二,初始化,使目录变成Git可管理的仓库 执行: git i ...
- mysql 基础教程
创建数据库: CREATE DATABASE --DATABASE 或者 SCHEMA数据库集合 IF NOT EXISTS db_name CHARACTER SET utf8 COLLATE ut ...
- (10)Spring Boot修改端口号【从零开始学Spring Boot】
Spring boot 默认端口是8080,如果想要进行更改的话,只需要修改applicatoin.properties文件,在配置文件中加入: server.port=9090 常用配置: #### ...
- [bzoj3932][CQOI2015]任务查询系统_主席树
任务查询系统 bzoj-3932 CQOI-2015 题目大意:最近实验室正在为其管理的超级计算机编制一套任务管理系统,而你被安排完成其中的查询部分.超级计算机中的任务用三元组(Si,Ei,Pi)描述 ...
- codevs——T1219 骑士游历
http://codevs.cn/problem/1219/ 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题解 查看运行结果 题目描述 Desc ...
- xtrabackup增量备份mysql +MHA
http://blog.csdn.net/yanggd1987/article/category/2214421 https://www.centos.bz/2013/09/innobackupex- ...
- MySQL 面试题目
1, mysql的复制原理以及流程. (1)先问基本原理流程,3个线程以及之间的关联. (2)再问一致性,延时性,数据恢复. (3)再问各种工作遇到的复制bug的解决方法 2,mysql中myis ...