dinic算法的改进

来源:互联网 发布:中国照相馆 知乎 编辑:程序博客网 时间:2024/05/17 20:33

dinic算法的改进


保存邻接表是使用的是head数组,现在另设一个head2数组,存储的是每个节点x从head2[x]开始的边才会有增广路,这样减少了无用边的循环。并且head2数组只在全局初始化一次,即如果没有增广,该值只会逐渐减小直到0。
在HDU3572中使用该优化可使时间从998ms优化值156ms

附上代码

/*注释的地方是与平常dinic不同的地方,注意即可*/#include<cstdio>#include<iostream>#include<queue>#include<cstring>using namespace std;struct edge{    int y,l,next;};edge v[1000*1000+50];int tot;int head[1050];int head2[1050];//***int d[1050];int st,ed;int n,m;int p[550];int s[550];int e[550];int sump;void add(int x,int y,int l){    tot++;    v[tot].y=y; v[tot].l=l;    v[tot].next=head[x]; head[x]=tot;}bool bfs(){    for (int i=1;i<=ed;i++)    {        d[i]=0;    }    queue<int> q;    q.push(st);    d[st]=1;    int now=0;    head2[st]=head[st];//***    while (!q.empty())    {        now=q.front();        q.pop();        for (int i=head[now];i;i=v[i].next)        {            if (v[i].l>0 && !d[v[i].y])            {                d[v[i].y]=d[now]+1;                head2[v[i].y]=head[v[i].y];//***                q.push(v[i].y);            }        }    }    return d[ed];}int dinic(int x,int flow){    if (x==ed) return flow;    int temp=0;    for (int i=head2[x];i;i=v[i].next)//***    {        if (d[v[i].y]==d[x]+1 && v[i].l>0)        {            int k=dinic(v[i].y,min(flow-temp,v[i].l));            if (k)            {                temp+=k;                v[i].l-=k;                v[i^1].l+=k;            }        }        head2[x]=i;//***        if (temp==flow) return flow;    }    return temp;}int T;int main(){    scanf("%d",&T);    for (int tt=1;tt<=T;tt++)    {        scanf("%d%d",&n,&m);        int l=1000;        int r=0;        sump=0;        for (int i=1;i<=n;i++)        {            scanf("%d%d%d",&p[i],&s[i],&e[i]);            l=min(l,s[i]);            r=max(e[i],r);            sump+=p[i];        }        tot=1;        memset(head,0,sizeof(head));        memset(head2,0,sizeof(head2));        st=n+r-l+2;        ed=n+r-l+3;        for (int i=1;i<=n;i++)        {            add(st,i,p[i]);            add(i,st,0);            for (int j=s[i];j<=e[i];j++)            {                add(i,n+j-l+1,1);                add(n+j-l+1,i,0);            }        }        for (int i=l;i<=r;i++)        {            add(n+i-l+1,ed,m);            add(ed,n+i-l+1,0);        }        int maxflow=0;        int now=0;        while (bfs())        {            maxflow+=dinic(st,0x3f3f3f3f);        }        printf("Case %d: ",tt);        if (maxflow==sump)        {            printf("Yes\n");        }        else        {            printf("No\n");        }        printf("\n");    }    return 0;}
0 0
原创粉丝点击