标签:style http io ar os sp for div on
蒟蒻zyk又来发水题题解了。。。
题目链接:http://poj.org/problem?id=2135
题意:无向边的最小费用最大流,注意要另建超级源点和超级汇点,加一条无向边相当于加4条有向边。
#include <iostream> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <algorithm> #include <queue> #define MAXV 10100 #define MAXE 1000100 #define INF 0x3f3f3f3f using namespace std; struct edge { int u,v,w,cap,next; }edges[MAXE]; int n,m; int head[MAXV],nCount=-1; int last[MAXV],dist[MAXV]; bool inQueue[MAXV]; void AddEdge(int U,int V,int W,int C) { //正向边 edges[++nCount].u=U; edges[nCount].v=V; edges[nCount].w=W; edges[nCount].cap=C; edges[nCount].next=head[U]; head[U]=nCount; //反向边 edges[++nCount].u=V; edges[nCount].v=U; edges[nCount].w=-W; edges[nCount].cap=0; edges[nCount].next=head[V]; head[V]=nCount; } bool SPFA(int s,int t) { queue<int>q; memset(last,-1,sizeof(last)); memset(dist,INF,sizeof(dist)); memset(inQueue,false,sizeof(inQueue)); inQueue[s]=true; dist[s]=0; q.push(s); while(!q.empty()) { int u=q.front(); q.pop(); inQueue[u]=false; for(int p=head[u];p!=-1;p=edges[p].next) { if(edges[p].cap>0) { int v=edges[p].v; if(dist[u]+edges[p].w<dist[v]) { dist[v]=dist[u]+edges[p].w; last[v]=p; if(!inQueue[v]) { inQueue[v]=true; q.push(v); } } } } } return dist[t]<INF; } int MCMF(int s,int t) //求s到t的最小费用最大流 { int sumcost=0,sumflow=0,flow; while(SPFA(s,t)) { flow=INF; for(int i=last[t];i!=-1;i=last[edges[i].u]) { if(edges[i].cap<flow) flow=edges[i].cap; } for(int i=last[t];i!=-1;i=last[edges[i].u]) { edges[i].cap-=flow; //正向边减去容量 edges[i^1].cap+=flow; //反向边加容量 } sumcost+=dist[t]; sumflow+=flow; } return sumcost; } int main() { while(scanf("%d%d",&n,&m)!=EOF) { memset(head,-1,sizeof(head)); AddEdge(0,1,0,2); //建立超级源点 AddEdge(n,n+1,0,2); //建立超级汇点 for(int i=1;i<=m;i++) { int u,v,w; scanf("%d%d%d",&u,&v,&w); AddEdge(u,v,w,1); AddEdge(v,u,w,1); } printf("%d\n",MCMF(0,n+1)); } return 0; }
标签:style http io ar os sp for div on
原文地址:http://blog.csdn.net/qpswwww/article/details/41119711