zoukankan      html  css  js  c++  java
  • P2153 [SDOI2009]晨跑

    比较显然的拆点费用流。

    按照套路,网络流跑两个关键字的最优化问题时,可以把所有的第一个关键字都乘第二个关键字的和,最后计算答案时直接取膜即可。

    #include<bits/stdc++.h>
    #define il inline
    #define vd void
    typedef long long ll;
    il int gi(){
        int x=0,f=1;
        char ch=getchar();
        while(!isdigit(ch)){
            if(ch=='-')f=-1;
            ch=getchar();
        }
        while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
        return x*f;
    }
    const int maxn=403,maxm=100000;
    int fir[maxn],dis[maxm],nxt[maxm],w[maxm],cnt,id=1;ll cost[maxm];
    il vd link(int a,int b,int c,ll d){
        nxt[++id]=fir[a],fir[a]=id,dis[id]=b,w[id]=c,cost[id]=d;
        nxt[++id]=fir[b],fir[b]=id,dis[id]=a,w[id]=0,cost[id]=-d;
    }
    int in[201],out[201],S,T;
    il bool Mincost(ll&Total){
        static int que[maxn],inq[maxn],lst[maxn],hd,tl;
        static ll dist[maxn];
        for(int i=1;i<=cnt;++i)dist[i]=1000000000000000ll,lst[i]=0;
        hd=tl=0;que[tl++]=S;inq[S]=1;
        dist[S]=0;
        while(hd^tl){
            int x=que[hd];
            for(int i=fir[x];i;i=nxt[i])
                if(w[i]&&dist[dis[i]]>dist[x]+cost[i]){
                    dist[dis[i]]=dist[x]+cost[i];lst[dis[i]]=i;
                    if(!inq[dis[i]])inq[dis[i]]=1,que[tl++]=dis[i],tl%=maxn;
                }
            ++hd,hd%=maxn;inq[x]=0;
        }
        if(lst[T]==0)return 0;
        for(int i=lst[T];i;i=lst[dis[i^1]])Total+=cost[i],--w[i],++w[i^1];
        return 1;
    }
    int main(){
    #ifndef ONLINE_JUDGE
        freopen("2153.in","r",stdin);
        freopen("2153.out","w",stdout);
    #endif
        int n=gi(),m=gi(),a,b,c;
        for(int i=1;i<=n;++i)in[i]=++cnt,out[i]=++cnt;
        S=++cnt,T=++cnt;
        link(S,out[1],1e9,-1000000000000ll);link(in[n],T,1e9,0);
        for(int i=1;i<=n;++i)link(in[i],out[i],1,0);
        while(m--)a=gi(),b=gi(),c=gi(),link(out[a],in[b],1,c);
        ll ans=0;while(Mincost(ans));
        printf("%lld %lld
    ",(-ans+1000000000000ll)/1000000000000ll,ans%1000000000000ll+1000000000000ll);
        return 0;
    }
    
    
  • 相关阅读:
    函数和指针
    SQL Server 2005 存储过程
    位数组
    C的名字空间
    C奇特的声明
    位字段
    Git忽略规则
    常用C库简介
    《SQL Server 2005 编程入门经典》第一到十二章
    Linus:利用二级指针删除单向链表
  • 原文地址:https://www.cnblogs.com/xzz_233/p/9807531.html
Copyright © 2011-2022 走看看