hdu 2435 dinic算法模板+最小割性质

来源:互联网 发布:大数据时代变革与挑战 编辑:程序博客网 时间:2024/06/06 04:57
#include<stdio.h>#include<queue>#include<string.h>using namespace std;#define inf 0x3fffffff#define N 200struct node {int v,w,next;}bian[N*N*2],fbian[N*N*2];int head[N],yong,tt;int  deep[N];//深度保留层次图void addedge(int u,int v,int w) {bian[yong].v=v;bian[yong].w=w;bian[yong].next=head[u];head[u]=yong++;}int bfs(int s) {//寻找层次图  int i,cur;  queue<int>q;  memset(deep,-1,sizeof(deep));  q.push(s);  deep[s]=1;  while(!q.empty()) {    cur=q.front();    q.pop();    for(i=head[cur];i!=-1;i=bian[i].next)        if(bian[i].w&&deep[bian[i].v]==-1) {            deep[bian[i].v]=deep[cur]+1;            q.push(bian[i].v);        }  }  if(deep[tt]!=-1)return 1;  return 0;}int Min(int a,int b) {return a>b?b:a;}int dfs(int s,int limit) {//多次dfs    int i,cost=0,flow,v;   // printf("%d %d\n",s,head[s]);    if(s==tt) {return limit;}    for(i=head[s];i!=-1;i=bian[i].next) {        v=bian[i].v;      //  printf("%d %d %d\n",s,v,bian[i].w);        if(bian[i].w&&deep[v]==deep[s]+1) {             //   printf("%d\n",v);            flow=dfs(v,Min(limit-cost,bian[i].w));            if(flow>0) {                bian[i].w-=flow;                bian[i^1].w+=flow;                cost+=flow;                if(limit==cost)break;            }            else                deep[v]=-1;//如果再次遇到v就不会进行下去        }    }    return cost ;}int dinic_maxflow(int s) {//dinic算法模板  int sum=0;while(bfs(1)) {//for(i=1;i<=tt;i++) //  printf("%d\n",deep[i]);    sum+=dfs(1,inf);}  return sum;}/*int visit[N];void dfs1(int u) {  int i;  visit[u]=1;  for(i=head[u];i!=-1;i=bian[i].next) {    if(bian[i].w&&visit[bian[i].v]==0)    dfs1(bian[i].v);  }}*/int ds[N],dds,dt[N],ddt;int fhead[N],fyong;int main() {       int t,m,n,i,j,k,maxflow,ma,fma,fa,fb;       scanf("%d",&t);       while(t--) {        scanf("%d%d",&n,&m);        yong=0;        memset(head,-1,sizeof(head));        while(m--) {            scanf("%d%d%d",&i,&j,&k);            addedge(i,j,k);//加入边            addedge(j,i,0);//退边        }        tt=n;        maxflow=dinic_maxflow(1);//最大流模板      dds=0;ddt=0;    /*  memset(visit,0,sizeof(visit));      dfs1(1);*/      for(i=2;i<n;i++) {//根据deep是否为-1可以得到源点集和汇点集        if(deep[i]!=-1)//源点集            ds[++dds]=i;        else            dt[++ddt]=i;//汇点集      }     // printf("%d %d\n",dds,ddt);    /* for(i=2;i<n;i++) {        if(visit[i])            ds[++dds]=i;        else            dt[++ddt]=i;     }*/        for(i=0;i<yong;i++)//保留残留网络            fbian[i]=bian[i];            for(i=1;i<=n;i++)//保留残留网络                fhead[i]=head[i];            ma=0;            fyong=yong;//保留残留网络            for(i=1;i<=dds;i++)//枚举                for(j=1;j<=ddt;j++) {                    fa=ds[i];fb=dt[j];                    for(k=0;k<yong;k++)//加入了新边,必须跟新为原来的求最大流一次的残留网络                        bian[k]=fbian[k];            memset(head,0,sizeof(head));            for(k=1;k<=n;k++) //因为加入了新边,所以必须跟新head的值为原来的残留网络                head[k]=fhead[k];                yong=fyong;//                        addedge(fa,fb,inf);                        addedge(fb,fa,0);                        fma=dinic_maxflow(1);                        if(fma>ma)//求出最大值                            ma=fma;                }                printf("%d\n",ma+maxflow);       }return 0;}


0 0
原创粉丝点击