//这题不会做,看了大牛的解题报告才知道用费用流可解,不怎么熟悉,今天调试了一上午,终于弄明白了,其实最小费用流本身很好理解,最小费用在求最大流的时候和一般的网络流的盲目增广不同,而是选最小费用来增广,最后到不能增广为止,这题的难点就是怎么去构建成最小费用流;
详细思路具体参见下面这两个人的博客:
http://blog.csdn.net/flying_stones_sure/article/details/8010155
http://blog.csdn.net/kksleric/article/details/8009882
//贴个自己的代码留念一下:
#include<stdio.h> #include<string.h> #include<queue> #include<algorithm> using namespace std; #define inf 1000000 int map[110][110],n,m; int dis[210],vis[210]; int pre[210],cap[210][210],cost[210][210]; queue <int > que; int bfs(int start,int end) { int i; for(i=0;i<=n;i++) dis[i]=inf; memset(vis,0,sizeof(vis)); dis[start]=0; que.push(start); vis[start]=1; while(!que.empty()) { int u=que.front(); vis[u]=0; que.pop(); for(i=0;i<=n;i++) { if(cap[u][i]>0&&dis[u]+cost[u][i]<dis[i]) { dis[i]=dis[u]+cost[u][i]; pre[i]=u; if(!vis[i]) { vis[i]=1; que.push(i); } } } } return dis[end]<inf; } int mcmf(int start,int end) { int i,res=0,Min; while(bfs(start,end)) { Min=inf; for(i=end;i!=start;i=pre[i]) if(cap[pre[i]][i]<Min) Min=cap[pre[i]][i]; for(i=end;i!=start;i=pre[i]) { res+=Min*cost[pre[i]][i]; cap[pre[i]][i]-=Min; cap[i][pre[i]]+=Min; } } return res; } int main() { int a,b,c,i,j,k,g,p; while(scanf("%d%d%d",&n,&m,&k),n+m+k) { for(i=0;i<=n;i++) { map[i][i]=0; for(j=i+1;j<=n;j++) { map[i][j]=inf; map[j][i]=inf; } } for(i=1;i<=m;i++) { scanf("%d%d%d",&a,&b,&c); if(map[a][b]>c) { map[a][b]=c; map[b][a]=c; } } for(g=0;g<=n;g++) { for(i=0;i<=n;i++) { for(j=0;j<=n;j++) { if(map[i][g]+map[g][j]<map[i][j]) map[i][j]=map[i][g]+map[g][j]; } } } p=n;n=2*n+2; for(i=0;i<=n;i++) { for(j=0;j<=n;j++) { cost[i][j]=inf; cap[i][j]=0; } } for(i=1;i<=p;i++) { for(j=i+1;j<=p;j++) { if(map[i][j]<inf) { cost[i+p+1][j]=map[i][j]; cost[j][i+p+1]=-map[i][j]; cap[i+p+1][j]=inf; } } cap[i][i+p+1]=1; cost[i][i+p+1]=-inf; cost[i+p+1][i]=inf; if(map[0][i]<inf) { cap[i+p+1][n]=inf; cost[i+p+1][n]=map[i][0]; cost[n][i+p+1]=-map[i][0]; cap[p+1][i]=inf; cost[p+1][i]=map[0][i]; cost[i][p+1]=-map[0][i]; } } cap[0][p+1]=k; cost[0][p+1]=0; cap[p+1][n]=k; cost[p+1][n]=0; printf("%d\n",mcmf(0,n)+p*inf); } return 0; } /* 5 5 2 0 1 1 1 2 1 2 3 1 3 5 1 0 4 1 */