HDU — 3416 Marriage Match IV(最大流+最短路)
来源:互联网 发布:打开数据漫游会收费没 编辑:程序博客网 时间:2024/06/05 11:15
题目大意:
有n个城市,m条道路,给出起点,终点,求从起点到终点一共有多少条不同的最短路径;
思路分析:
先用最短路求出最短路径,在此基础上建边,权值为1(表示一条边只能走一遍),跑一边最大流即可;
注意源点和汇点不一定就是1和n这两个点;
代码实现:
#include<cstdio>#include<cstring>#include<queue>#include<vector>#include<iostream>#define Max(a,b) ((a)>(b)?(a):(b))#define Min(a,b) ((a)<(b)?(a):(b))using namespace std;const int N=1010;const int M=200010;const int INF=0x3f3f3f3f;int n,m,s,t,top,head[N],gap[N],cur[N],dis[N],d[N],vis[N],pre[N];struct Edge{ int to,next,flow;}edge[M];struct E{ int to,val; E(int _to=0,int _val=0):to(_to),val(_val){}};vector<E> v[N];void Addedge(int from,int to,int val){ edge[top].to=to,edge[top].next=head[from],edge[top].flow=val,head[from]=top++; edge[top].to=from,edge[top].next=head[to],edge[top].flow=0,head[to]=top++;}void Spfa(){ queue<int> q; memset(vis,0,sizeof(vis)); memset(d,0x3f,sizeof(d)); q.push(s); d[s]=0; while(!q.empty()){ int u=q.front(); q.pop(); vis[u]=0; for(int i=0;i<v[u].size();++i){ int tmp=v[u][i].to; if(d[tmp]>d[u]+v[u][i].val){ d[tmp]=d[u]+v[u][i].val; if(!vis[tmp]){ vis[tmp]=1; q.push(tmp); } } } }}void Bfs(){ queue<int> q; memset(gap,0,sizeof(gap)); memset(dis,-1,sizeof(dis)); gap[0]=1,dis[t]=0; q.push(t); while(!q.empty()){ int u=q.front(); q.pop(); for(int i=head[u];i+1;i=edge[i].next){ if(dis[edge[i].to]==-1){ dis[edge[i].to]=dis[u]+1; gap[dis[edge[i].to]]++; q.push(edge[i].to); } } }}int Sap(){ Bfs(); memset(pre,-1,sizeof(pre)); for(int i=1;i<=n;++i) cur[i]=head[i]; int u=s,i,cur_flow,max_flow=0,neck,tmp; while(dis[s]<n){ if(u==t){ cur_flow=INF; for(int i=s;i!=t;i=edge[cur[i]].to){ if(cur_flow>edge[cur[i]].flow){ neck=i; cur_flow=edge[cur[i]].flow; } } for(int i=s;i!=t;i=edge[cur[i]].to){ tmp=cur[i]; edge[tmp].flow-=cur_flow; edge[tmp^1].flow+=cur_flow; } max_flow+=cur_flow; u=neck; } int i; for(i=cur[u];i!=-1;i=edge[i].next) if(edge[i].flow&&dis[u]==dis[edge[i].to]+1) break; if(i!=-1){ cur[u]=i; pre[edge[i].to]=u; u=edge[i].to; }else{ if(--gap[dis[u]]==0) break; cur[u]=head[u]; int mindis=n; for(i=head[u];i!=-1;i=edge[i].next){ if(edge[i].flow&&mindis>dis[edge[i].to]) mindis=dis[edge[i].to]; } dis[u]=mindis+1; gap[dis[u]]++; if(u!=s) u=pre[u]; } } return max_flow;}int main(){ int T,v1,v2,va; scanf("%d",&T); while(T--){ scanf("%d%d",&n,&m); memset(head,-1,sizeof(head)); for(int i=1;i<=n;++i) v[i].clear(); top=0; for(int i=0;i<m;++i){ scanf("%d%d%d",&v1,&v2,&va); if(v1==v2) continue; v[v1].push_back(E(v2,va)); } scanf("%d%d",&s,&t); Spfa(); for(int i=1;i<=n;++i) for(int j=0;j<v[i].size();++j) if(d[v[i][j].to]==d[i]+v[i][j].val) Addedge(i,v[i][j].to,1); int res=Sap(); printf("%d\n",res); }}
0 0
- HDU 3416 Marriage Match IV(最短路+最大流)
- hdu 3416 Marriage Match IV (最短路+最大流)
- HDU 3416 Marriage Match IV(最短路+最大流)
- HDU-3416 Marriage Match IV(最大流+最短路)
- HDU 3416 Marriage Match IV(最短路+最大流)
- hdu 3416 Marriage Match IV 【网络最大流+最短路】
- [HDU 3416]Marriage Match IV[最大流][最短路]
- HDU-3416 Marriage Match IV(最短路+最大流)
- HDU 3416 —— Marriage Match IV(最短路+最大流)
- HDU — 3416 Marriage Match IV(最大流+最短路)
- HDU 3416 Marriage Match IV(最短路,网络流)
- HDU 3416 Marriage Match IV(最短路+网络流之最大流)
- hdu 3416 Marriage Match IV 【图论-网络流-最短路+最大流(spfa + Dinic)】
- HDU 3416 Marriage Match IV(最短路+最大流(sap))
- HDU 3416 Marriage Match IV (最短路判断建边+最大流)
- hdoj 3416 Marriage Match IV 【最大流 + 最短路】
- HDOJ 3416 Marriage Match IV【最短路+最大流】
- HDU 3416 Marriage Match IV(中等,好题) [最大流]最短路+最大流
- Eclipse Java注释模板设置详解
- StringTokenizer类的用法
- 8086cpu中的标志寄存器与比较指令
- maven
- Unity5.1 新的网络引擎UNET(四) UNET Remote Actions
- HDU — 3416 Marriage Match IV(最大流+最短路)
- C语言宏定义
- MySQL新建用户,授权,删除用户,修改密码
- 网络编程Socket
- 王阳明心学感悟1——勇敢地剖析自己的内心
- 25匹马,5个赛道,取前3
- UITableView 表示图学习笔记
- 理解一般指针和指向指针的指针
- 实例说明RPC的使用