sgu 194 无源汇有上下界的最大流(最大流模板dinic加优化)

来源:互联网 发布:易语言时时彩做号源码 编辑:程序博客网 时间:2024/06/05 09:22
模板类型的题具体参考国家集训队论文:http://wenku.baidu.com/view/0f3b691c59eef8c75fbfb35c.html
参考博客:http://blog.csdn.net/qq172108805/article/details/7783010
#include<stdio.h>#include<string.h>#include<queue>using namespace std;#define  N  300#define inf 0x3fffffffstruct node {   int u,v,w,next;}bian[N*N*3];int fee[N],bb[N*N*2];int head[N],yong,dis[N],work[N];void init(){yong=0;memset(head,-1,sizeof(head));}void addbian(int u,int v,int w) {bian[yong].u=u;bian[yong].v=v;bian[yong].w=w;bian[yong].next=head[u];head[u]=yong++;}void add(int u,int v,int w) {addbian(u,v,w);addbian(v,u,0);}int min(int a,int b){return a<b?a:b;}int bfs(int s,int t){    memset(dis,-1,sizeof(dis));    queue<int>q;    q.push(s);    dis[s]=0;    while(!q.empty())    {        int u=q.front();        q.pop();        for(int i=head[u];i!=-1;i=bian[i].next)        {            int v=bian[i].v;            if(bian[i].w&&dis[v]==-1)            {                dis[v]=dis[u]+1;                q.push(v);                if(v==t)                    return 1;            }        }    }    return 0;}int dfs(int  s,int limit,int t){    if(s==t)return limit;    for(int &i=work[s];i!=-1;i=bian[i].next)    {        int v=bian[i].v;        if(bian[i].w&&dis[v]==dis[s]+1)        {            int tt=dfs(v,min(limit,bian[i].w),t);            if(tt)            {                bian[i].w-=tt;                bian[i^1].w+=tt;                return tt;            }        }    }    return 0;}int dinic(int s,int t){    int ans=0;    while(bfs(s,t))    {        memcpy(work,head,sizeof(head));        while(int tt=dfs(s,inf,t))            ans+=tt;    }    return ans;}int main(){  int n,m,i,a,b,c,d,suma,f,s,t,w[N];   while(scanf("%d%d",&n,&m)!=EOF) {      init();    s=0;t=n+1;      suma=0;      memset(w,0,sizeof(w));     for(i=0;i<m;i++) {        scanf("%d%d%d%d",&a,&b,&c,&d);        add(a,b,d-c);        w[b]+=c;        w[a]-=c;        bb[i]=d;      }      for(i=1;i<=n;i++) {        if(w[i]>0) {                suma+=w[i];        add(s,i,w[i]);        }        if(w[i]<0)add(i,t,-w[i]);      }      f=dinic(s,t);      if(f==suma) {        printf("YES\n");        for(i=0;i<m;i++)            printf("%d\n",bb[i]-bian[i*2].w);      }      else        printf("NO\n");   }return 0;}

0 0
原创粉丝点击