Hdu 3416 Marriage Match IV 最大流sap+最短路径spfa
来源:互联网 发布:js登录表单验证 编辑:程序博客网 时间:2024/04/30 06:26
题意:n个点之间有m条有向边,求从源点s到汇点t的最短路径有多少条,最短路径之间不能共用边。
利用前几天学的两个算法写了这题,感觉对两个算法还是不太熟练。
这题的关键还是在于建图。先用最短路径算法分别计算s和t点到各点的最短距离,若一条边的弧尾到s的距离+弧头到t的距离+边的权值=s到t的最短路径,那这条边必定在最短路径上。选择这些边建立一张新图,边的权值都为1,然后用最大流算法sap计算条数。
#include <iostream>#include<queue>#include<cstdio>#include<cstring>#include<cmath>#define INF 0x7fffffff#define N 200100using namespace std;struct node{ int to,next,w;}e[N*8];int n,cnt,head[N];void init(){ cnt=0; memset(head,-1,sizeof(head));}void add(int u,int v,int w){ e[cnt].to=v; e[cnt].next=head[u]; e[cnt].w=w; head[u]=cnt++; e[cnt].to=u; e[cnt].next=head[v]; e[cnt].w=0; head[v]=cnt++;}int cur[N],gap[N],dis[N],pre[N];int sap(int s,int t){ for(int i=1;i<=n;i++) { cur[i]=head[i]; gap[i]=dis[i]=0; } int ans=0,mmin=INF,u; u=pre[s]=s; gap[s]=n; while(dis[s]<n) { int flag=0; for(int &i=cur[u];i!=-1;i=e[i].next) { int v=e[i].to; if(dis[u]==dis[v]+1&&e[i].w) { flag=1; mmin=min(mmin,e[i].w); pre[v]=u; u=v; if(u==t) { ans+=mmin; while(u!=s) { u=pre[u]; e[cur[u]].w-=mmin; e[cur[u]^1].w+=mmin; } mmin=INF; } break; } } if(flag) continue; int md=n; for(int i=head[u];i!=-1;i=e[i].next) { int v=e[i].to; if(e[i].w&&dis[v]<md) { md=dis[v]; cur[u]=i; } } if(--gap[dis[u]]==0) return ans; gap[dis[u]=md+1]++; u=pre[u]; } return ans;}void addedge(int u,int v,int w){ e[cnt].to=v; e[cnt].next=head[u]; e[cnt].w=w; head[u]=cnt++;}int d[N],vis[N],q[N];void spfa(int u){ for(int i=1;i<=n;i++) d[i]=INF,vis[i]=0; d[u]=0; vis[u]=1; q[0]=u; int k=0; while(k>=0) { int t=q[k--]; vis[t]=0; for(int i=head[t];i!=-1;i=e[i].next) { int c=e[i].to,w=e[i].w; if(d[c]>d[t]+w) { d[c]=d[t]+w; if(!vis[c]) vis[c]=1,q[++k]=c; } } }}int d1[N],d2[N],u[N],v[N],w[N];int main(){ int T; cin>>T; while(T--) { int m; cin>>n>>m; init(); for(int i=1;i<=m;i++) { scanf("%d%d%d",&u[i],&v[i],&w[i]); addedge(u[i],v[i],w[i]); } int s,t; cin>>s>>t; spfa(s); memcpy(d1,d,sizeof(d)); init(); for(int i=1;i<=m;i++) addedge(v[i],u[i],w[i]); spfa(t); memcpy(d2,d,sizeof(d)); init(); for(int i=1;i<=m;i++) if(u[i]!=v[i]&&d1[u[i]]+d2[v[i]]+w[i]==d1[t]) add(u[i],v[i],1); cout<<sap(s,t)<<endl; }}
1 0
- Hdu 3416 Marriage Match IV 最大流sap+最短路径spfa
- hdu 3416 Marriage Match IV 最大流 最短路径
- Marriage Match IV(最短路径+最大流)
- HDU 3416 Marriage Match IV(spfa+最大流)
- 【HDU】 3416 Marriage Match IV(最大流+SPFA)
- hdu 3416 Marriage Match IV【SPFA+最大流Dinic】
- HDU 3416 Marriage Match IV【SPFA+最大流】
- HDU 3416 Marriage Match IV (SPFA+最大流)
- Marriage Match IV (hdu 3416 网络流+spfa最短路)
- hdu 3416 Marriage Match IV 【图论-网络流-最短路+最大流(spfa + Dinic)】
- HDU 3416 Marriage Match IV(最短路+最大流(sap))
- HDU3416 Marriage Match IV(spfa+最大流SAP)
- 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(最大流+最短路)
- pat1013:数素数
- 算法竞赛入门经典 习题2-10 排列(permutation)
- 【nova】liberty版本openstack在线调整云主机大小
- [JAVA · 初级]:6.特殊关键字:this
- js下载文件
- Hdu 3416 Marriage Match IV 最大流sap+最短路径spfa
- 123
- 匿名函数与闭包
- ecshop怎么得到商品属性的值
- Android开发涉及到的英文
- 《Java实战开发经典》第六章6.3
- [leetcode 156]Binary Tree Upside Down
- 归并排序(解析及代码实现)
- 2016蓝桥杯假期任务之《翻硬币 》