网络流

来源:互联网 发布:淘宝活动标题怎么写 编辑:程序博客网 时间:2024/06/02 13:54
#include<iostream>//最小费用最大流 #include<memory.h>using namespace std;const int N=100;int map[2*N+2][2*N+2];//0为源点 1-n老师 n+1-2n类型 2N+1为汇点 保留的是边的权值(费用) int flow[2*N+2][2*N+2];//流量int path[2*N+2];//记录节点i在此次增广中的前驱int n;int ans=0;void input(){cin>>n;int x;for (int i=1;i<=n;i++)for (int j=1;j<=n;j++){cin>>x;map[i][j+n]=x;map[j+n][i]=-x;flow[i][j+n]=1;}for (int i=1;i<=n;i++){map[0][i]=0;flow[0][i]=1;}for (int i=1;i<=n;i++){map[i+n][2*n+1]=0;flow[i+n][2*n+1]=1;}return;}int shrtpth[2*N+2];//源点到其余点的最短路径int frm[2*N+1];//记录前驱 int Queue[5*N+1];//队列bool work()//spfa找增广路 {for (int i=0;i<=2*N+1;i++)shrtpth[i]=-32767;shrtpth[0]=0;int R,L;R=L=1;Queue[1]=0;for (;L<=R;L++){for (int i=0;i<=2*n+1;i++)//枚举每次被松弛的顶点即边[Queue[L]][i]if (flow[Queue[L]][i]>0)//存在流量if (map[Queue[L]][i]+shrtpth[Queue[L]]>shrtpth[i]){shrtpth[i]=map[Queue[L]][i]+shrtpth[Queue[L]];frm[i]=Queue[L];//记前驱 Queue[++R]=i;//i入队列}}if (shrtpth[2*n+1]==-32767)return false;int i=2*n+1;ans+=shrtpth[2*n+1];while (i!=0)//每次找前驱 {flow[frm[i]][i]--;flow[i][frm[i]]++;i=frm[i];}return true;}void all_clear(){   memset(flow,0,sizeof(flow));return;}int main(){all_clear();input();while(work());cout<<ans;return 0;}


 

原创粉丝点击