- 先用flyd求出所有最短路,之后用最短路建图就网络流。
- 重点是如何利用最短路建图!!
-
-
-
- #include<cstdio>
- #include<cstring>
- #include<queue>
- #define find_min(a,b) a<b?a:b
- using namespace std;
- const int N = 210;
- const int MAX = 9999999999;
- struct Edge{
- int s,e,v,next;
- }edge[5*N];
- int e_num,head[N],d[N],sp,tp;
- int n,dist[N][N],mat[N][N];
- void AddEdge(int a,int b,int c){
- edge[e_num].s=a; edge[e_num].e=b; edge[e_num].v=c;
- edge[e_num].next=head[a]; head[a]=e_num++;
- edge[e_num].s=b; edge[e_num].e=a; edge[e_num].v=0;
- edge[e_num].next=head[b]; head[b]=e_num++;
- }
- int bfs(){
- queue <int> q;
- memset(d,-1,sizeof(d));
- d[sp]=0;
- q.push(sp);
- while(!q.empty()){
- int cur=q.front();
- q.pop();
- for(int i=head[cur];i!=-1;i=edge[i].next){
- int u=edge[i].e;
- if(d[u]==-1 && edge[i].v>0){//没有标记,且可行流大于0
- d[u]=d[cur]+1;
- q.push(u);
- }
- }
- }
- return d[tp] != -1;//汇点是否成功标号,也就是说是否找到增广路
- }
- int dfs(int a,int b){//a为起点
- int r=0;
- if(a==tp)return b;
- for(int i=head[a];i!=-1 && r<b;i=edge[i].next){
- int u=edge[i].e;
- if(edge[i].v>0 && d[u]==d[a]+1){
- int x=find_min(edge[i].v,b-r);
- x=dfs(u,x);
- r+=x;
- edge[i].v-=x;
- edge[i^1].v+=x;
- }
- }
- if(!r)d[a]=-2;
- return r;
- }
- void dinic(int sp,int tp){
- int total=0,t;
- while(bfs()){
- while(t=dfs(sp,MAX))
- total+=t;
- }
- printf("%d\n",total);
- }
- int main()
- {
- int i,j,k;
- while(~scanf("%d",&n)){
- for(i=0;i<n;i++){
- for(j=0;j<n;j++){
- scanf("%d",&mat[i][j]);
- if(i==j)mat[i][j]=0;
- if(mat[i][j]==-1)mat[i][j]=MAX;
- dist[i][j]=mat[i][j];
- }
- }scanf("%d%d",&sp,&tp);
- if(sp!=tp){
- for(k=0;k<n;k++){
- for(i=0;i<n;i++)
- if(dist[i][k]<MAX)for(j=0;j<n;j++)
- if(dist[k][j]<MAX)dist[i][j]=find_min(dist[i][j],dist[i][k]+dist[k][j]);
- }
- e_num=0;
- memset(head,-1,sizeof(head));
- for(i=0;i<n;i++){
- if(dist[sp][i]<MAX)for(j=0;j<n;j++)
- if(dist[j][tp]<MAX && mat[i][j]<MAX && dist[sp][i]+mat[i][j]+dist[j][tp]==dist[sp][tp])AddEdge(i,j,1);
- }
- dinic(sp,tp);
- }
- else puts("inf");
- }
- return 0;
- }
给定有向图,每条边只能用一次,求给定两点间有几条最短路。
最新推荐文章于 2025-01-13 19:34:10 发布
本文介绍了一种结合最短路径算法Flyd与网络流技术解决特定问题的方法。通过Flyd算法预处理所有点之间的最短路径,再依据这些最短路径构建网络流图,最终使用Dinic算法寻找最大流。适用于需要同时考虑路径长度与流量限制的问题场景。

7610

被折叠的 条评论
为什么被折叠?



