HDU3416 Marriage Match IV(最短路,网络流,最大流,SPFA,ISAP算法)
2018-01-12 16:49
387 查看
Problem Description
Do not sincere non-interference。 Like that show, now starvae also takepart in a show, but it take place between city A and B. Starvae is in
city A and girls are in city B. Every time starvae can get to city B
and make a data with a girl he likes. But there are two problems with
it, one is starvae must get to B within least time, it’s said that he
must take a shortest path. Other is no road can be taken more than
once. While the city starvae passed away can been taken more than
once.
So, under a good RP, starvae may have many chances to get to city B.
But he don’t know how many chances at most he can make a data with the
girl he likes . Could you help starvae?
Input
The first line is an integer T indicating the case number.(1<=T<=65)For each case,there are two integer n and m in the first line (
2<=n<=1000, 0<=m<=100000 ) ,n is the number of the city and m is the
number of the roads.
Then follows m line ,each line have three integers
a,b,c,(1<=a,b<=n,0
Output
Output a line with a integer, means the chances starvae can get atmost.
Sample Input
3 7 8 1 2 1 1 3 1 2 4 1 3 4 1 4 5 1 4 6 1 5 7 1 6 7 1 1 7 6 7 1 2 1 2 3 1 1 3 3 3 4 1 3 5 1 4 6 1 5 6 1 1 6 2 2 1 2 1 1 2 2 1 2
Sample Output
2 1 1
思路
首先4000
是题意,一个人要从一个城市走到另一个城市,每次都走最短路,但是每次走的路不能是同一条,问一共有多少种不同的走法。
输入是这样给出的,首先是T组数据,然后是两个数n和m,代表有n个点和m条边。然后有m行数据,每行是三个数u,v,w,代表从u到v的权值是w。然后是两个数,代表了起点和终点.
首先我们的思路是,从图中剔除不是最短路的边,然后把剩下的边(最短路上的边)建图,然后边权为1,求最大流,求出的值就是有多少种走法。
那么问题来了,如何判断一条边(u,v)是不是最短路的边呢。
我们假定起点是
st,终点为
ed,当前要判断的边是(u,v),从起点开始的最短路数组为dis1[],从终点开始的最短路数组为dis2[],那么我们要判断边是不是在最短路上,只要:
dis1[u]+(u,v)+dis2[v]==dis1[ed]
成立就可以确定边在最短路上,我们根据这个条件,把在最短路上的边建图,求一下最大流就是答案
SAP算法的模板用了
kuangbin的。
代码
#include <cstdio> #include <cstring> #include <cctype> #include <stdlib.h> #include <string> #include <map> #include <iostream> #include <stack> #include <cmath> #include <queue> #include <vector> #include <algorithm> using namespace std; typedef long long ll; #define inf 0x3f3f3f3f #define mem(a,b) memset(a,b,sizeof(a)) const int N=1000+20; const int M=2*100000+20; int top; int h ,pre ,g ,first ,cur ;//h[i]记录每个节点的高度,pre[i]记录前驱,g[i]表示距离为i个节点数有多少个 struct node { int v,next,cap; } E[M]; void init() { mem(first,-1); top=0; } void add_edge(int u,int v,int c) { E[top].v=v; E[top].cap=c; E[top].next=first[u]; first[u]=top++; E[top].v=u; E[top].cap=0; E[top].next=first[v]; first[v]=top++; } int sap(int start,int end,int nodenum) { memset(h,0,sizeof(h)); memset(g,0,sizeof(g)); memcpy(cur,first,sizeof(first)); int u=pre[start]=start,maxflow=0,aug=-1; g[0]=nodenum; while(h[start]<nodenum) { loop: for(int &i=cur[u]; i!=-1; i=E[i].next) { int v=E[i].v; if(E[i].cap&&h[u]==h[v]+1) { if(aug==-1||aug>E[i].cap) aug=E[i].cap; pre[v]=u; u=v; if(v==end) { maxflow+=aug; for(u=pre[u]; v!=start; v=u,u=pre[u]) { E[cur[u]].cap-=aug; E[cur[u]^1].cap+=aug; } aug=-1; } goto loop; } } int mindis=nodenum; for(int i=first[u]; i!=-1; i=E[i].next) { int v=E[i].v; if(E[i].cap&&mindis>h[v]) { cur[u]=i; mindis=h[v]; } } if((--g[h[u]])==0)break; g[h[u]=mindis+1]++; u=pre[u]; } return maxflow; } int n,m; struct SPFA { void init() { mem(first,-1); mem(vis,0); mem(dis,0); len=1; } int first ,len,vis ,dis ; struct node { int u,v,w,next; } G[M]; void add_edge(int u,int v,int w) { G[len].v=v,G[len].w=w; G[len].next=first[u]; first[u]=len++; } void spfa(int st) { for(int i=1; i<=n; i++) { dis[i]=inf; vis[i]=0; } dis[st]=0; vis[st]=1; queue<int>q; q.push(st); while(!q.empty()) { st=q.front(); q.pop(); vis[st]=0; for(int i=first[st]; i!=-1; i=G[i].next) { int v=G[i].v,w=G[i].w; if(dis[v]>dis[st]+w) { dis[v]=dis[st]+w; if(!vis[v]) { vis[v]=1; q.push(v); } } } } } } ac1,ac2; int main() { int t,st,ed,u,v,w; scanf("%d",&t); while(t--) { init(); ac1.init(); ac2.init(); scanf("%d%d",&n,&m); for(int i=1; i<=m; i++) { scanf("%d%d%d",&u,&v,&w); ac1.add_edge(u,v,w); ac2.add_edge(v,u,w); } scanf("%d%d",&st,&ed); ac1.spfa(st); ac2.spfa(ed); for(int i=1; i<=n; i++) { for(int j=ac1.first[i]; ~j; j=ac1.G[j].next) { u=i,v=ac1.G[j].v,w=ac1.G[j].w; if(ac1.dis[u]+w+ac2.dis[v]==ac1.dis[ed]) add_edge(u,v,1); } } printf("%d\n",sap(st,ed,n)); } return 0; }
相关文章推荐
- hdu 3416 Marriage Match IV 【图论-网络流-最短路+最大流(spfa + Dinic)】
- hdu3416 Marriage Match IV【最短路+最大流】
- hdu3416 Marriage Match IV(网络流+最短路)
- hdu3416 Marriage Match IV(最短路+最大流)
- HDU3416 Marriage Match IV(最大流+最短路)
- HDU 3416 Marriage Match IV(最短路+最大流)
- HDOJ 3416 Marriage Match IV【最短路+最大流】
- HDU 3416 —— Marriage Match IV(最短路+最大流)
- HDU-3416 Marriage Match IV(最短路+最大流)
- O - Marriage Match IV - hdu 3416(最短路+最大流)
- Marriage Match IV HDU3461 网络流+最短路spfa
- 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+最大流)
- HDU 3416 Marriage Match IV (最短路径,网络流,最大流)
- HDU-3416 Marriage Match IV(最大流+最短路)
- HDU 3416 Marriage Match IV (求最短路的条数,最大流)