HDU — 3416 Marriage Match IV(最大流+最短路)
2015-07-12 15:44
603 查看
题目大意:
有n个城市,m条道路,给出起点,终点,求从起点到终点一共有多少条不同的最短路径;
思路分析:
先用最短路求出最短路径,在此基础上建边,权值为1(表示一条边只能走一遍),跑一边最大流即可;
注意源点和汇点不一定就是1和n这两个点;
代码实现:
有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 ,gap ,cur ,dis ,d ,vis ,pre ; 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 ; 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); } }
相关文章推荐
- WINCE驱动程序快速入门
- 经管学习笔记(1)
- Performance冷启动简单测试
- HDU 1892 See you~
- 编译器错误消息: CS0006: 未能找到元数据文件
- C#值类型与引用类型
- Android开发(三十二)——延时
- 屏幕适配
- Five Invaluable Techniques to Improve Regex Performance
- Five Invaluable Techniques to Improve Regex Performance
- ORACLE开启/关闭归档模式
- Five Invaluable Techniques to Improve Regex Performance
- Android开发(三十一)——重复引用包错误Conversion to Dalvik format failed
- Android开发(二十九)——layout_weight的含义
- 杭电 hdu 1033 (水题) 但英文特难,题意很难理解
- Palindrome Linked List
- 黑马程序员 集合类
- C语言中函数
- ubuntu将命令写在一个文件里,执行文件,source命令
- HDU 3549 Flow Problem 流问题(最大流,入门)