• luogu P2153 [SDOI2009]晨跑 |费用流


    题目描述

    Elaxia最近迷恋上了空手道,他为自己设定了一套健身计划,比如俯卧撑、仰卧起坐等 等,不过到目前为止,他坚持下来的只有晨跑。 现在给出一张学校附近的地图,这张地图中包含N个十字路口和M条街道,Elaxia只能从 一个十字路口跑向另外一个十字路口,街道之间只在十字路口处相交。Elaxia每天从寝室出发 跑到学校,保证寝室编号为1,学校编号为N。 Elaxia的晨跑计划是按周期(包含若干天)进行的,由于他不喜欢走重复的路线,所以 在一个周期内,每天的晨跑路线都不会相交(在十字路口处),寝室和学校不算十字路 口。Elaxia耐力不太好,他希望在一个周期内跑的路程尽量短,但是又希望训练周期包含的天 数尽量长。 除了练空手道,Elaxia其他时间都花在了学习和找MM上面,所有他想请你帮忙为他设计 一套满足他要求的晨跑计划。

    存在 (1 ightarrow n) 的边存在。这种情况下,这条边只能走一次。

    输入格式

    第一行:两个数 (N,M)。表示十字路口数和街道数。 接下来M行,每行3个数a,b,c,表示路口a和路口b之间有条长度为c的街道(单向)。

    输出格式

    两个数,第一个数为最长周期的天数,第二个数为满足最长天数的条件下最短的路程长度。

    说明/提示

    对于30%的数据,(N ≤ 20,M ≤ 120)

    对于100%的数据,(N ≤ 200,M ≤ 20000)


    拆点建图

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<queue>
    #include<cstring>
    using namespace std;
    const int N=4015,M=4e5+10,inf=0x3f3f3f3f;
    int nxt[M],head[N],go[M],edge[M],cost[M],tot=1;
    inline void add(int u,int v,int o1,int o2){
        nxt[++tot]=head[u],head[u]=tot,go[tot]=v,edge[tot]=o1,cost[tot]=o2;
        nxt[++tot]=head[v],head[v]=tot,go[tot]=u,edge[tot]=0,cost[tot]=-o2;
    }
    
    int dis[N],ret,s,t;
    bool vis[N];
    inline bool spfa(){
        memset(dis,0x3f,sizeof(dis)); dis[s]=0;
        queue<int>q; q.push(s);
        while(q.size()){
            int u=q.front(); q.pop(); vis[u]=0;
            for(int i=head[u];i;i=nxt[i]){
                int v=go[i];
                if(edge[i]&&dis[v]>dis[u]+cost[i]){
                    dis[v]=dis[u]+cost[i];
                    if(!vis[v])q.push(v),vis[v]=1;
                }
            }
        }
        return dis[t]!=inf;
    }
    
    int dinic(int u,int flow){
        if(u==t)return flow;
        int rest=flow,k;
        vis[u]=1;
        for(int i=head[u];i&&rest;i=nxt[i]){
            int v=go[i];
            if(edge[i]&&!vis[v]&&dis[v]==dis[u]+cost[i]){
                k=dinic(v,min(rest,edge[i]));
                if(!k)dis[v]=-1;
                ret+=k*cost[i];
                edge[i]-=k;
                edge[i^1]+=k;
                rest-=k;
            }
        }
        vis[u]=0;
        return flow-rest;
    }
    int n,m;
    signed main(){
        cin>>n>>m;
        add(1,1+n,inf,0);
        add(n,n+n,inf,0);
        for(int i=2;i<n;i++)add(i,i+n,1,0);
        for(int i=1,u,v,o;i<=m;i++){
            scanf("%d%d%d",&u,&v,&o);
            add(u+n,v,1,o);
        }
        s=1; t=n+n;
        int flow=0,maxflow=0;
        while(spfa())
        while(flow=dinic(s,inf))maxflow+=flow;
        cout<<maxflow<<' '<<ret<<endl;
    }
    
  • 相关阅读:
    java编译错误No enclosing instance of type TestFrame is accessible. Must qualify the allocation with an enclosing instance of type TestFrame (e.g. x.new A(
    java 2中创建线程方法
    动态规划基本思想
    关于eclipse编译一个工程多个main函数
    java Gui初识
    Eclipse中java项目的打包
    java 播放声音
    把资源文件夹导入到eclipse中
    Java建立JProgressBar
    How to grant permissions to a custom assembly that is referenced in a report in Reporting Services
  • 原文地址:https://www.cnblogs.com/naruto-mzx/p/12207559.html
Copyright © 2020-2023  润新知