• bzoj2324营救皮卡丘


    费用流。

    建图比较重要。

    1.S->id[0][0] flow=k。 表示k条路径。

    2.S->id[i][0] flow=1, 每次消耗1流量就补充1流量。

    3.id[i][1]->T flow=1, 保证每个点都经过一次。

    4.id[i][0]->id[j][1] 存在一条路。

    这样建图每个点都会被经过一次,而且都是从编号小的点转移过来,满足题目条件。

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int maxn = 500 + 10;
    const int maxm = 100000 + 10;
    const int inf = 0x3f3f3f3f;
    
    int g[maxn],v[maxm],next[maxm],f[maxm],c[maxm],eid;
    int G[maxn][maxn];
    int n,m,k,S,T;
    int id[maxn][2],vid;
    int dist[maxn],pre[maxn];
    bool inque[maxn];
    int q[maxm];
    
    void addedge(int a,int b,int F,int C) {
        v[eid]=b; f[eid]=F; c[eid]= C; next[eid]=g[a]; g[a]=eid++;
        v[eid]=a; f[eid]=0; c[eid]=-C; next[eid]=g[b]; g[b]=eid++;    
    }
    
    void build() {
        scanf("%d%d%d",&n,&m,&k);
        memset(G,0x3f,sizeof(G));
        memset(g,-1,sizeof(g));
        for(int i=0;i<=n;i++) G[i][i]=0;
        for(int i=1,a,b,l;i<=m;i++) {
            scanf("%d%d%d",&a,&b,&l);
            if(G[a][b]>l) G[a][b]=G[b][a]=l;
        }
        for(int i=0;i<=n;i++) {
            id[i][0]=++vid;
            id[i][1]=++vid;    
        }
        S=++vid; T=++vid;
        addedge(S,id[0][0],k,0);
        for(int i=1;i<=n;i++) {
            addedge(S,id[i][0],1,0);
            addedge(id[i][1],T,1,0);    
        }
        for(int k=0;k<=n;k++)
        for(int i=0;i<=n;i++)
        for(int j=0;j<=n;j++) {
            G[i][j]=min(G[i][j],G[i][k]+G[k][j]);
            if(k==j && i<j && G[i][j]<inf) {
                addedge(id[i][0],id[j][1],inf,G[i][j]);
            }
        }
    }
    
    bool SPFA() {
        int u,l,r; 
        memset(dist,0x3f,sizeof(dist));
        dist[S]=0;
        l=r=0;
        q[r++]=S;
        
        while(l<r) {
            inque[u=q[l++]]=0;
            for(int i=g[u];~i;i=next[i]) {
                if(f[i] && dist[v[i]]>dist[u]+c[i]) {
                dist[v[i]]=dist[u]+c[i];
                pre[v[i]]=i;
                if(!inque[v[i]]) inque[q[r++]=v[i]]=1;
                }
            }
        }
        return dist[T]<inf;
    }
    
    int augment() {
        int aug=inf,res=0;
        for(int i=T;i!=S;i=v[pre[i]^1]) aug=min(aug,f[pre[i]]);
        for(int i=T;i!=S;i=v[pre[i]^1]) {
            f[pre[i]]-=aug;
            f[pre[i]^1]+=aug;
            res+=c[pre[i]]*aug;    
        }
        return res;
    }
    
    void solve() {
        int res=0;
        while(SPFA()) res+=augment();
        printf("%d
    ",res);
    }
    
    int main() {
        build();
        solve();
        return 0;
    }
  • 相关阅读:
    Navicat 导入数据报错 --- 1153
    VS2015创建的Asp.net WebApi默认项目在CentOS7+Mono4.2.2+jexus5.8运行不起来的解决方案
    CentOS 6.5安装MySQL中文乱码问题解决
    Centos上Apache重启,mysql重启, nginx 重启方法
    linux自己带的apache重新启动
    CentOS Linux系统下更改Apache默认网站目录
    C语言王国探秘一
    《JavaScript权威指南》学习笔记 第一天。
    《JavaScript权威指南》学习笔记 第二天 下好一盘大棋
    Js里面的强制类型转换
  • 原文地址:https://www.cnblogs.com/invoid/p/5582176.html
Copyright © 2020-2023  润新知