hdu3416 最短路+最大流
题意:有 n 点 m 边,有出发点 A 到达点 B ,只允许走原图中的最短路,但每条边只允许被走一次,问最多能找出多少条边不重复的最短路
一开始做到的时候瞎做了一发最短路,WA了之后也知道显然不对,就放着了,后来打了今年的多校,再做到的时候发现和多校第一场的1007一样的……最短路+网络流就行了,只不过第一次做这个的时候我还不知道网络流是啥,不会做也正常啦。
首先对于原图跑一遍最短路求出每个点距离 A 点的最短路,然后对于每一条边,如果它的权值等于它连接的两点的最短路的差值的时候,就说明这条路是最短路上的边,将这个边加入网络流的建图中,流量定为1表示这条边只能用一次,这样跑一遍最大流就能直接解决问题了。
- #include<stdio.h>
- #include<string.h>
- #include<algorithm>
- #include<queue>
- #include<vector>
- using namespace std;
- typedef pair<int,int> pii;
- const int maxm=;
- const int INF=0x3f3f3f3f;
- struct cmp{
- bool operator()(pii a,pii b){
- return a.first>b.first;
- }
- };
- int head[],point[],val[],nxt[],size;
- bool vis[];
- int dis[],n,s,p,fa[],pa[];
- struct edge{ //弧的结构体,变量:弧的出发点、结束点、容量、流量
- int from,to,c,f;
- edge(int a,int b,int m,int n):from(a),to(b),c(m),f(n){}
- };
- struct dinic{
- int m,s,t; //边数、源点标号、汇点标号
- vector<edge>e; //边
- vector<int>g[maxm]; //g[i][j]表示第i个点出发的第j条边在e中的编号
- bool vis[maxm];
- int d[maxm],cur[maxm]; //d为源点到点的距离,cur为当前遍历到的边
- void init(int n){ //初始化,n为点数量(标号0~n-1)
- for(int i=;i<n+;i++)g[i].clear();
- e.clear();
- }
- void add(int a,int b,int v){ //加入弧和反向弧
- e.push_back(edge(a,b,v,)); //正向弧容量v,反向弧容量0
- e.push_back(edge(b,a,,));
- m=e.size();
- g[a].push_back(m-);
- g[b].push_back(m-);
- }
- bool bfs(){
- memset(vis,,sizeof(vis));
- queue<int>q;
- q.push(s);
- d[s]=;
- vis[s]=;
- while(!q.empty()){
- int u=q.front();q.pop();
- for(int i=;i<g[u].size();i++){
- edge tmp=e[g[u][i]];
- if(!vis[tmp.to]&&tmp.c>tmp.f){
- vis[tmp.to]=;
- d[tmp.to]=d[u]+;
- q.push(tmp.to);
- }
- }
- }
- return vis[t];
- }
- int dfs(int x,int a){
- if(x==t||a==)return a;
- int flow=,f;
- for(int& i=cur[x];i<g[x].size();i++){
- edge &tmp=e[g[x][i]];
- if(d[x]+==d[tmp.to]&&(f=dfs(tmp.to,min(a,tmp.c-tmp.f)))>){
- tmp.f+=f;
- e[g[x][i]^].f-=f;
- flow+=f;
- a-=f;
- if(a==)break;
- }
- }
- if(!flow)d[x]=-;
- return flow;
- }
- int mf(int s,int t){ //在主函数中使用的函数,求s到t的最大流
- this->s=s;
- this->t=t;
- int flow=;
- while(bfs()){
- memset(cur,,sizeof(cur));
- flow+=dfs(s,INF);
- }
- return flow;
- }
- };
- void add(int a,int b,int v){
- point[size]=b;
- val[size]=v;
- nxt[size]=head[a];
- head[a]=size++;
- }
- void dij(){
- int i;
- priority_queue<pii,vector<pii>,cmp>q;
- memset(dis,0x3f,sizeof(dis));
- memset(fa,-,sizeof(fa));
- dis[s]=;
- q.push(make_pair(dis[s],s));
- while(!q.empty()){
- pii u=q.top();
- q.pop();
- if(u.first>dis[u.second])continue;
- for(i=head[u.second];~i;i=nxt[i]){
- int j=point[i],v=u.first+val[i];
- if(!vis[i]&&dis[j]>v){
- dis[j]=v;
- fa[j]=u.second;
- pa[j]=i;
- q.push(make_pair(dis[j],j));
- }
- }
- }
- }
- int main(){
- int t;
- scanf("%d",&t);
- for(int q=;q<=t;q++){
- int m,i;
- memset(head,-,sizeof(head));
- memset(vis,,sizeof(vis));
- size=;
- scanf("%d%d",&n,&m);
- for(i=;i<=m;i++){
- int a,b,v;
- scanf("%d%d%d",&a,&b,&v);
- if(a!=b){
- add(a,b,v);
- }
- }
- scanf("%d%d",&s,&p);
- dinic d;
- dij();
- for(i=;i<=n;++i){
- for(int j=head[i];~j;j=nxt[j]){
- int k=point[j];
- if(dis[i]+val[j]==dis[k])d.add(i,k,);
- }
- }
- printf("%d\n",d.mf(s,p));
- }
- return ;
- }
hdu3416 最短路+最大流的更多相关文章
- hdu5294||2015多校联合第一场1007 最短路+最大流
http://acm.hdu.edu.cn/showproblem.php? pid=5294 Problem Description Innocent Wu follows Dumb Zhang i ...
- BZOJ 3931: [CQOI2015]网络吞吐量( 最短路 + 最大流 )
最短路 + 最大流 , 没什么好说的... 因为long long WA 了两次.... ------------------------------------------------------- ...
- 【最短路+最大流】上学路线@安徽OI2006
目录 [最短路+最大流]上学路线@安徽OI2006 PROBLEM SOLUTION CODE [最短路+最大流]上学路线@安徽OI2006 PROBLEM 洛谷P4300 SOLUTION 先在原图 ...
- P3376 【模板】网络最大流——————Q - Marriage Match IV(最短路&最大流)
第一道题是模板题,下面主要是两种模板,但都用的是Dinic算法(第二个题也是) 第一题: 题意就不需要讲了,直接上代码: vector代码: 1 //invalid types 'int[int]' ...
- HDU-3416 Marriage Match IV 最短路+最大流 找各最短路的所有边
题目链接:https://cn.vjudge.net/problem/HDU-3416 题意 给一个图,求AB间最短路的条数(每一条最短路没有重边.可有重复节点) 思路 首先把全部最短路的边找出来,再 ...
- hdu3416+hdu6582(最短路+最大流)
题意 hdu3416: 给一个图,边不能重复选,问有多少个最短路 hdu6582: 给一个图,问最少删除边权多少的边后,最短路长度增加 分析 边不能重复选这个条件可以想到边权为1,跑最大流,所以我们可 ...
- hdu3416 Marriage Match IV【最短路+最大流】
转载请注明出处,谢谢:http://www.cnblogs.com/KirisameMarisa/p/4297581.html ---by 墨染之樱花 题目链接:http://acm.hdu.ed ...
- hdu3416 Marriage Match IV 最短路+ 最大流
此题的大意:给定一幅有向图,求起点到终点(都是固定的)的不同的最短路有多少条.不同的最短路是说不能有相同的边,顶点可以重复.并且图含有平行边. 看了题以后,就想到暴力,但是暴力往往是不可取的.(暴力的 ...
- 【BZOJ-3931】网络吞吐量 最短路 + 最大流
3931: [CQOI2015]网络吞吐量 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 1228 Solved: 524[Submit][Stat ...
随机推荐
- JS 数组去重!!!
var arr = [1,2,3,1,1,1,3,5,3,6,2]; var newArr=[]; for(var i = 0; i < arr.length-1; i++){ var onOf ...
- Linux下tmpfs与ramfs的区别
ramfs是Linux下一种基于RAM做存储的文件系统.在使用过程中你就可以把ramfs理解为在普通的HDD上建立了一个文件系统,而现在HDD被替换成了RAM,因为是RAM做存储所以会有很高的存储 ...
- js面向对象(构造函数与继承)
深入解读JavaScript面向对象编程实践 Mar 9, 2016 面向对象编程是用抽象方式创建基于现实世界模型的一种编程模式,主要包括模块化.多态.和封装几种技术. 对JavaScript而言,其 ...
- (转)面向移动设备的HTML5开发框架
(原)http://www.cnblogs.com/itech/archive/2013/07/27/3220352.html 面向移动设备的HTML5开发框架 转自:http://blogrea ...
- android-volley-at-a-glance
http://liubin.org/2013/05/27/android-volley-at-a-glance/ http://www.androidhive.info/2014/05/android ...
- 2016-1-15 抽屉效果实现demo
// // ViewController.m // 抽屉 // // Created by Mac on 16/1/15. // Copyright © 2016年 Mac. All rights r ...
- Objective-C determine data network type of the iOS device
Im on an application that receive data from server, the problem is when user connect to cellular dat ...
- 解决关于打开plist文件乱码问题,plist转换为xml文件的txt文件!
自己是程序员,干嘛不自己写代码完成?下载工具还不一定管用!具体解决方案如下: 1,获得内容 NSArray *dictionary = [NSArray arrayWithContentsOfFile ...
- 第一个Sprint冲刺第七天
讨论成员:邵家文.李新.朱浩龙.陈俊金 讨论问题:怎样添加功能 讨论地点:宿舍 遇到问题:编写代码的思路不完整,很混乱 工作进度: 队员工作照:
- 动画(Animation) 、 高级动画(Core Animation)
1 演示UIImage制作的动画 1.1 问题 UIImage动画是IOS提供的最基本的动画,通常用于制作一些小型的动画,本案例使用UIImage制作一个小狗跑动的动画,如图-1所示: 图-1 1.2 ...