标签:
Time Limit: 2000MS | Memory Limit: 32768K | |
Total Submissions: 25514 | Accepted: 13287 |
Description
Input
Output
Sample Input
2 1 1 2 (0,1)20 (1,0)10 (0)15 (1)20 7 2 3 13 (0,0)1 (0,1)2 (0,2)5 (1,0)1 (1,2)8 (2,3)1 (2,4)7 (3,5)2 (3,6)5 (4,2)7 (4,3)5 (4,5)1 (6,0)5 (0)5 (1)2 (3)2 (4)1 (5)4
Sample Output
15 6
#include<stdio.h> #include<string.h> #include<stack> #include<queue> #include<algorithm> #define MAX 1100 #define MAXM 40010 #define INF 0x7fffff using namespace std; struct node { int from,to,cap,flow,next; }edge[MAXM]; int n,m,np,nc; int ans,head[MAX]; int vis[MAX];//用bfs求路径时判断当前点是否进队列, int dis[MAX];//当前点到源点的距离 int cur[MAX];//保存该节点正在参加计算的弧避免重复计算 void init() { ans=0; memset(head,-1,sizeof(head)); } void add(int u,int v,int w) { node E1={u,v,w,0,head[u]}; edge[ans]=E1; head[u]=ans++; node E2={v,u,0,0,head[v]}; edge[ans]=E2; head[v]=ans++; } void getmap() { int a, b, d; while(m--) { scanf(" (%d,%d)%d", &a, &b, &d); add(a+1, b+1, d); } while(np--) { scanf(" (%d)%d", &b, &d); add(0, b+1, d);//超级源 } while(nc--) { scanf(" (%d)%d", &a, &d); add(a+1, n+1, d);//超级汇 } } int bfs(int beg,int end) { int i; memset(vis,0,sizeof(vis)); memset(dis,-1,sizeof(dis)); queue<int>q; while(!q.empty()) q.pop(); vis[beg]=1; dis[beg]=0; q.push(beg); while(!q.empty()) { int u=q.front(); q.pop(); for(i=head[u];i!=-1;i=edge[i].next)//遍历所有的与u相连的边 { node E=edge[i]; if(!vis[E.to]&&E.cap>E.flow)//如果边未被访问且流量未满继续操作 { dis[E.to]=dis[u]+1;//建立层次图 vis[E.to]=1;//将当前点标记 if(E.to==end)//如果当前点搜索到终点则停止搜索 返回1表示有从原点到达汇点的路径 return 1; q.push(E.to);//将当前点入队 } } } return 0;//返回0表示未找到从源点到汇点的路径 } int dfs(int x,int a,int end)//把找到的这条边上的所有当前流量加上a(a是这条路径中的最小残余流量) { //int i; if(x==end||a==0)//如果搜索到终点或者最小的残余流量为0 return a; int flow=0,f; for(int& i=cur[x];i!=-1;i=edge[i].next)//i从上次结束时的弧开始 { node& E=edge[i]; if(dis[E.to]==dis[x]+1&&(f=dfs(E.to,min(a,E.cap-E.flow),end))>0)//如果 {//bfs中我们已经建立过层次图,现在如果 dis[E.to]==dis[x]+1表示是我们找到的路径 //如果dfs>0表明最小的残余流量还有,我们要一直找到最小残余流量为0 E.flow+=f;//正向边当前流量加上最小的残余流量 edge[i^1].flow-=f;//反向边 flow+=f;//总流量加上f a-=f;//最小可增流量减去f if(a==0) break; } } return flow;//所有边加上最小残余流量后的值 } int Maxflow(int beg,int end) { int flow=0; while(bfs(beg,end))//存在最短路径 { memcpy(cur,head,sizeof(head));//复制数组 flow+=dfs(beg,INF,end); } return flow;//最大流量 } int main() { int i,j; while(scanf("%d%d%d%d",&n,&np,&nc,&m)!=EOF) { init(); getmap(); printf("%d\n",Maxflow(0,n+1)); } return 0; }
poj 1459 Power Network【建立超级源点,超级汇点】
标签:
原文地址:http://www.cnblogs.com/tonghao/p/4915659.html