• bzoj3876: [Ahoi2014&Jsoi2014]支线剧情


    我真是看题之神zzzzzzz,在任意时刻都可以直接回起点啊

    假装自己会过这个算法

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    const int _=1e2;
    const int maxn=300+10;
    const int maxe=5*1e3+_;
    const int inf=(1<<28);
    
    struct node
    {
        int x,y,c,d,next;
    }a[2*(maxe+3*maxn)];int len,last[maxn];
    void ins(int x,int y,int c,int d)
    {
    //    printf("%d %d %d %d
    ",x,y,c,d);
        len++;
        a[len].x=x;a[len].y=y;a[len].c=c;a[len].d=d;
        a[len].next=last[x];last[x]=len;
        
        len++;
        a[len].x=y;a[len].y=x;a[len].c=0;a[len].d=-d;
        a[len].next=last[y];last[y]=len;
    }
    
    int st,ed;
    int pre[maxn],c[maxn],d[maxn],ans;
    int list[maxn];bool v[maxn];
    bool spfa()
    {
        memset(d,63,sizeof(d));d[st]=0;c[st]=(1<<30);
        memset(v,false,sizeof(v));v[st]=true;
        int head=1,tail=2;list[1]=st;
        while(head!=tail)
        {
            int x=list[head];
            for(int k=last[x];k;k=a[k].next)
            {
                int y=a[k].y;
                if(a[k].c>0&&d[y]>d[x]+a[k].d)
                {
                    d[y]=d[x]+a[k].d;
                    c[y]=min(a[k].c,c[x]);
                    pre[y]=k;
                    if(v[y]==false)
                    {
                        v[y]=true;
                        list[tail]=y;
                        tail++;if(tail==maxn)tail=1;
                    }
                }
            }
            v[x]=false;
            head++;if(head==maxn)head=1;
        }
        if(d[ed]==d[0])return false;
        else
        {
            int y=ed;ans+=c[ed]*d[ed];
            while(y!=st)
            {
                int k=pre[y];
                a[k].c-=c[ed];
                a[k^1].c+=c[ed];
                y=a[k].x;
            }
            return true;
        }
    }
    
    int u[maxn];
    int main()
    {
        freopen("a.in","r",stdin);
        freopen("a.out","w",stdout);
        int n,m,x,dd;
        scanf("%d",&n);n++; st=n+1,ed=n+2;
        ans=0; len=1;
        for(int i=1;i<n;i++)
        {
            scanf("%d",&m);
            for(int j=1;j<=m;j++)
            {
                 scanf("%d%d",&x,&dd);
                ins(i,x,inf,dd),u[i]--,u[x]++;
                ans+=dd;
            }
            ins(i,n,inf,0);
        }
        ins(n,1,inf,0);
        for(int i=1;i<=n;i++)
                 if(u[i]<0)ins(i,ed,-u[i],0);
            else if(u[i]>0)ins(st,i,u[i],0);
        
        while(spfa());
        printf("%d
    ",ans);
                
        return 0;
    }
  • 相关阅读:
    纯js实现字符串formate方法
    C#实现json压缩和格式化
    简单的前端校验框架实现
    快速拷贝文件
    0012 移除元素
    0011 删除链表的倒数第N个节点
    0010 最长公共前缀
    0009 合并两个有序链表
    0008 合并K个排序链表
    0007 回文数
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/10565563.html
Copyright © 2020-2023  润新知