HDU3416 Marriage Match IV【网络流】

来源:互联网 发布:如何运行协同过滤算法 编辑:程序博客网 时间:2024/06/05 11:26

题意:一个有向图,求最短路的条数,一条边不能用两次


思路:如果没有最短路这个限制的话,边的容量为1,最大流就是路的条数。加了这个限制,我们跑一边SPFA,用最短路中的边去建图,一条边(x,y,w),若d[x] + w == d[y],这条边就是最短路中的边。建完图,再求最大流


#include<stdio.h>#include<iostream>#include<string.h>#include<string>#include<stdlib.h>#include<math.h>#include<vector>#include<list>#include<map>#include<set>#include<stack>#include<queue>#include<algorithm>#include<numeric>#include<functional>using namespace std;typedef long long ll;typedef pair<int,int> pii;const int maxn = 1e5+5;struct data{int from,to,next,val;}Edge[maxn];int d[maxn],inq[maxn];int head[maxn],tot;struct edge {int to,cf,rev;};vector<edge> G[maxn];int lev[maxn],iter[maxn];void init(int n){memset(head,-1,sizeof head);tot = 0;for(int i = 0; i <= n; i++)G[i].clear();}void add(int x,int y,int val){Edge[tot].from = x;Edge[tot].to = y;Edge[tot].val = val;Edge[tot].next = head[x];head[x] = tot++;}void spfa(int st,int en){queue<int> q;while(!q.empty())q.pop();memset(inq,0,sizeof inq);memset(d,0x3f,sizeof d);d[st] = 0;q.push(st);while(!q.empty()){int now = q.front();q.pop();inq[now] = 0;for(int i = head[now]; i != -1; i = Edge[i].next){int temp = Edge[i].to;if(d[now]+Edge[i].val < d[temp]){d[temp] = d[now]+Edge[i].val;if(!inq[temp]){inq[temp] = 1;q.push(temp);}}}}}void add2(int from, int to, int cap){G[from].push_back((edge){to,cap,G[to].size()});G[to].push_back((edge){from,0,G[from].size()-1});}void bfs(int s){memset(lev,-1,sizeof lev);queue<int> q;lev[s] = 0;q.push(s);while(!q.empty()){int v = q.front();q.pop();for(int i = 0; i < G[v].size(); i++){edge &e = G[v][i];if(e.cf > 0 && lev[e.to] < 0){lev[e.to] = lev[v] + 1;q.push(e.to);}}}}int dfs(int v,int t, int f){if(v == t) return f;for(int &i = iter[v]; i < G[v].size(); i++){edge &e = G[v][i];if(e.cf > 0 && lev[v] < lev[e.to]){int d = dfs(e.to, t, min(f,e.cf));if(d > 0){e.cf -= d;G[e.to][e.rev].cf += d;return d;}}}return 0;}int maxflow(int s,int t){int flow = 0;while(1){bfs(s);if(lev[t] < 0) return flow;memset(iter,0,sizeof iter);int f;while((f = dfs(s,t,0x3f3f3f3f)) > 0)flow += f;}}int main(void){int T,n,m;scanf("%d",&T);while(T--){scanf("%d%d",&n,&m);init(n);while(m--){int a,b,c;scanf("%d%d%d",&a,&b,&c);add(a,b,c);}int st,en;scanf("%d%d",&st,&en);spfa(st,en);for(int i = 0; i < tot; i++){int x = Edge[i].from;int y = Edge[i].to;if(d[x] + Edge[i].val == d[y])add2(x,y,1);}int ans = maxflow(st,en);printf("%d\n",ans);}return 0;}


原创粉丝点击