高分求教!
谢谢了!
1 个解决方案
#1
/**********************
最大流算法
***********************/
#include<stdio.h>
#include<limits.h>
#define abs(i) ((i)<0)?(-(i)):(i)
#define N 100
long limits[N][N],last[N],flow[N][N],n,m;
//limits数组记录容量, flow记录流量
// last记录某一点在增广路上的前趋:设为 i, 则正向弧标为 i, 反向弧标为-i
int Init();
int main()
{
long i,j,k,used[N],v1,v2,cost,s,t,delta,sum; //delta可改进的流量
while((scanf("%ld%ld",&n,&m))!=EOF) //输入顶点数, 边数
{
Init();
s=1,t=n; // s为源点, t为汇点
for(i=0;i<m;i++)
{
scanf("%ld%ld%ld",&v1,&v2,&cost); //输入边及其相应的流量
limits[v1][v2]=cost;
}
while(1)
{
for(i=1;i<=n;i++)used[i]=0,last[i]=0;
last[s]=INT_MAX;
while(last[t]==0)
{
for(i=1;i<=n;i++)
if(last[i]&&!used[i])break;
//找一个已标号但未使用过的点
if(i>n)break;
for(j=1;j<=n;j++)
if(!last[j])
{
if(flow[i][j]<limits[i][j]) last[j]=i;
if(flow[j][i])last[j]=-i;
//找到点 i 的一个未被标号的后继
}
used[i]=1;
} /*程序的核心:增广路的求法*/
if(last[n]==0)break; //汇点未被标号, 则说明无增广路, 退出循环
for(i=n,delta=INT_MAX,k=INT_MAX;i!=1;)
{
j=last[i]; //找可调整的流量
if(j>0)k=limits[j][i]-flow[j][i];
else k=flow[i][j];
if(k<delta)delta=k;
i=abs(j);
}
for(i=n;i!=1;)
{
j=last[i];
if(j<0)flow[i][j]-=delta;
else flow[j][i]+=delta;
i=abs(j);
} //调整流量, 使其满足流量图的性质
}
for(i=1,sum=0;i<=n;i++)
{
if(flow[i][n])sum+=flow[i][n];
if(flow[n][i])sum-=flow[n][i];
} // 求最大流
printf("%ld\n",sum); //输出
}
return 0;
}
int Init()
{
long i,j;
for(i=1;i<=n;i++)
for(j=i;j<n;j++)
{
limits[i][j]=limits[j][i]=0;
flow[i][j]=flow[j][i]=0; //初始化流量, 容量为 0
}
return 0;
}
最大流算法
***********************/
#include<stdio.h>
#include<limits.h>
#define abs(i) ((i)<0)?(-(i)):(i)
#define N 100
long limits[N][N],last[N],flow[N][N],n,m;
//limits数组记录容量, flow记录流量
// last记录某一点在增广路上的前趋:设为 i, 则正向弧标为 i, 反向弧标为-i
int Init();
int main()
{
long i,j,k,used[N],v1,v2,cost,s,t,delta,sum; //delta可改进的流量
while((scanf("%ld%ld",&n,&m))!=EOF) //输入顶点数, 边数
{
Init();
s=1,t=n; // s为源点, t为汇点
for(i=0;i<m;i++)
{
scanf("%ld%ld%ld",&v1,&v2,&cost); //输入边及其相应的流量
limits[v1][v2]=cost;
}
while(1)
{
for(i=1;i<=n;i++)used[i]=0,last[i]=0;
last[s]=INT_MAX;
while(last[t]==0)
{
for(i=1;i<=n;i++)
if(last[i]&&!used[i])break;
//找一个已标号但未使用过的点
if(i>n)break;
for(j=1;j<=n;j++)
if(!last[j])
{
if(flow[i][j]<limits[i][j]) last[j]=i;
if(flow[j][i])last[j]=-i;
//找到点 i 的一个未被标号的后继
}
used[i]=1;
} /*程序的核心:增广路的求法*/
if(last[n]==0)break; //汇点未被标号, 则说明无增广路, 退出循环
for(i=n,delta=INT_MAX,k=INT_MAX;i!=1;)
{
j=last[i]; //找可调整的流量
if(j>0)k=limits[j][i]-flow[j][i];
else k=flow[i][j];
if(k<delta)delta=k;
i=abs(j);
}
for(i=n;i!=1;)
{
j=last[i];
if(j<0)flow[i][j]-=delta;
else flow[j][i]+=delta;
i=abs(j);
} //调整流量, 使其满足流量图的性质
}
for(i=1,sum=0;i<=n;i++)
{
if(flow[i][n])sum+=flow[i][n];
if(flow[n][i])sum-=flow[n][i];
} // 求最大流
printf("%ld\n",sum); //输出
}
return 0;
}
int Init()
{
long i,j;
for(i=1;i<=n;i++)
for(j=i;j<n;j++)
{
limits[i][j]=limits[j][i]=0;
flow[i][j]=flow[j][i]=0; //初始化流量, 容量为 0
}
return 0;
}
#1
/**********************
最大流算法
***********************/
#include<stdio.h>
#include<limits.h>
#define abs(i) ((i)<0)?(-(i)):(i)
#define N 100
long limits[N][N],last[N],flow[N][N],n,m;
//limits数组记录容量, flow记录流量
// last记录某一点在增广路上的前趋:设为 i, 则正向弧标为 i, 反向弧标为-i
int Init();
int main()
{
long i,j,k,used[N],v1,v2,cost,s,t,delta,sum; //delta可改进的流量
while((scanf("%ld%ld",&n,&m))!=EOF) //输入顶点数, 边数
{
Init();
s=1,t=n; // s为源点, t为汇点
for(i=0;i<m;i++)
{
scanf("%ld%ld%ld",&v1,&v2,&cost); //输入边及其相应的流量
limits[v1][v2]=cost;
}
while(1)
{
for(i=1;i<=n;i++)used[i]=0,last[i]=0;
last[s]=INT_MAX;
while(last[t]==0)
{
for(i=1;i<=n;i++)
if(last[i]&&!used[i])break;
//找一个已标号但未使用过的点
if(i>n)break;
for(j=1;j<=n;j++)
if(!last[j])
{
if(flow[i][j]<limits[i][j]) last[j]=i;
if(flow[j][i])last[j]=-i;
//找到点 i 的一个未被标号的后继
}
used[i]=1;
} /*程序的核心:增广路的求法*/
if(last[n]==0)break; //汇点未被标号, 则说明无增广路, 退出循环
for(i=n,delta=INT_MAX,k=INT_MAX;i!=1;)
{
j=last[i]; //找可调整的流量
if(j>0)k=limits[j][i]-flow[j][i];
else k=flow[i][j];
if(k<delta)delta=k;
i=abs(j);
}
for(i=n;i!=1;)
{
j=last[i];
if(j<0)flow[i][j]-=delta;
else flow[j][i]+=delta;
i=abs(j);
} //调整流量, 使其满足流量图的性质
}
for(i=1,sum=0;i<=n;i++)
{
if(flow[i][n])sum+=flow[i][n];
if(flow[n][i])sum-=flow[n][i];
} // 求最大流
printf("%ld\n",sum); //输出
}
return 0;
}
int Init()
{
long i,j;
for(i=1;i<=n;i++)
for(j=i;j<n;j++)
{
limits[i][j]=limits[j][i]=0;
flow[i][j]=flow[j][i]=0; //初始化流量, 容量为 0
}
return 0;
}
最大流算法
***********************/
#include<stdio.h>
#include<limits.h>
#define abs(i) ((i)<0)?(-(i)):(i)
#define N 100
long limits[N][N],last[N],flow[N][N],n,m;
//limits数组记录容量, flow记录流量
// last记录某一点在增广路上的前趋:设为 i, 则正向弧标为 i, 反向弧标为-i
int Init();
int main()
{
long i,j,k,used[N],v1,v2,cost,s,t,delta,sum; //delta可改进的流量
while((scanf("%ld%ld",&n,&m))!=EOF) //输入顶点数, 边数
{
Init();
s=1,t=n; // s为源点, t为汇点
for(i=0;i<m;i++)
{
scanf("%ld%ld%ld",&v1,&v2,&cost); //输入边及其相应的流量
limits[v1][v2]=cost;
}
while(1)
{
for(i=1;i<=n;i++)used[i]=0,last[i]=0;
last[s]=INT_MAX;
while(last[t]==0)
{
for(i=1;i<=n;i++)
if(last[i]&&!used[i])break;
//找一个已标号但未使用过的点
if(i>n)break;
for(j=1;j<=n;j++)
if(!last[j])
{
if(flow[i][j]<limits[i][j]) last[j]=i;
if(flow[j][i])last[j]=-i;
//找到点 i 的一个未被标号的后继
}
used[i]=1;
} /*程序的核心:增广路的求法*/
if(last[n]==0)break; //汇点未被标号, 则说明无增广路, 退出循环
for(i=n,delta=INT_MAX,k=INT_MAX;i!=1;)
{
j=last[i]; //找可调整的流量
if(j>0)k=limits[j][i]-flow[j][i];
else k=flow[i][j];
if(k<delta)delta=k;
i=abs(j);
}
for(i=n;i!=1;)
{
j=last[i];
if(j<0)flow[i][j]-=delta;
else flow[j][i]+=delta;
i=abs(j);
} //调整流量, 使其满足流量图的性质
}
for(i=1,sum=0;i<=n;i++)
{
if(flow[i][n])sum+=flow[i][n];
if(flow[n][i])sum-=flow[n][i];
} // 求最大流
printf("%ld\n",sum); //输出
}
return 0;
}
int Init()
{
long i,j;
for(i=1;i<=n;i++)
for(j=i;j<n;j++)
{
limits[i][j]=limits[j][i]=0;
flow[i][j]=flow[j][i]=0; //初始化流量, 容量为 0
}
return 0;
}