您的位置:首页 > 理论基础 > 计算机网络

【网络流】hdu3416 Marriage Match IV

2014-09-17 18:02 190 查看
题意:求起点到终点最多有几条可行路,这里可行路的定义是这样一条从起点到终点的路,他是最短路,而且这些可行路之间没有重合的边。

难度:2.5

题解:先以起点和终点为源各求一次单源最短路,然后保留所有的在最短路上的顶点和他们彼此之间的边,把这些保留下来的边的流量设为1, 最后求一次最大流。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
#include <vector>
using namespace std;
const int N=1002;
const int M=10000000;
int n,m,s,t,ans;
int dist
,map

,pre
;
bool mark
;
struct stu {
int to,cost;
};
vector<stu>g
;
void spfa(int start) {
int i,x;
memset(mark,false,sizeof(mark));
fill(dist,dist+n,M);dist[start]=0;
queue<int>q;
q.push(start);
while(!q.empty()) {
int e=q.front();q.pop();
mark[e]=false;
for(i=0;i<g[e].size();i++) {
x=g[e][i].to;
if(dist[x]>dist[e]+g[e][i].cost) {
dist[x]=dist[e]+g[e][i].cost;
if(!mark[x]) {q.push(x);mark[x]=true;}
}
}
}
}
void Max_flow() {
ans=0;
int i,minx;
while(1) {
queue<int>q;bool flag=false;
memset(mark,false,sizeof(mark));
mark[s]=true;
q.push(s);
while(!q.empty()) {
int cur=q.front();
q.pop();
if(cur==t) break;
for(i=0;i<n;i++) {
if(!mark[i]&&map[cur][i]>0) {
mark[i]=true;
q.push(i);
pre[i]=cur;
if(i==t) {flag=true;break;}
}
}
if(flag) break;
}
if(mark[t]==false) break;
minx=1000000;
for(i=t;i!=s;i=pre[i]) {
if(minx>map[pre[i]][i])
minx=map[pre[i]][i];
}
for(i=t;i!=s;i=pre[i]) {
map[pre[i]][i]-=minx;
map[i][pre[i]]+=minx;
}
ans+=minx;
}
}
int main() {
int tt,i,j,x,y,z;
cin>>tt;
while(tt--) {
cin>>n>>m;stu e1;
for(i=0;i<n;i++) g[i].clear();
for(i=0;i<m;i++) {
scanf("%d%d%d",&x,&y,&z);
x--;y--;
e1.to=y;e1.cost=z;
g[x].push_back(e1);
}
cin>>s>>t;s--;t--;
spfa(s);
if(dist[t]==M) {cout<<0<<endl;continue;}
memset(map,0,sizeof(map));
for(i=0;i<n;i++) {
for(j=0;j<g[i].size();j++) {
x=g[i][j].to;y=g[i][j].cost;
if(dist[i]+y==dist[x])
map[i][x]+=1;
}
}
Max_flow();
cout<<ans<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: