列表

详情


NC20328. [SDOI2009]晨跑

描述

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

输入描述

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

输出描述

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

示例1

输入:

7 10
1 2 1
1 3 1
2 4 1
3 4 1
4 5 1
4 6 1
2 5 5
3 6 6
5 7 1
6 7 1

输出:

2 11

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++ 解法, 执行用时: 190ms, 内存消耗: 1140K, 提交时间: 2021-11-02 10:43:48

#include<bits/stdc++.h>
using namespace std;
const int N=500;
const int M=1e5;
const int INF=0x3f3f3f3f;
const int mod=998244353;
int n,m,s,t;
int head[N+10],ver[(M+10)<<1],nxt[(M+10)<<1],edgef[(M+10)<<1],edgec[(M+10)<<1],tot=1;
int flow[N+10],dist[N+10],pre[N+10],vis[N+10];
void addedge(int x,int y,int c,int f){
    ver[++tot]=y;edgef[tot]=f;edgec[tot]=c;
    nxt[tot]=head[x];head[x]=tot;
    ver[++tot]=x;edgef[tot]=0;edgec[tot]=-c;
    nxt[tot]=head[y];head[y]=tot;
}
queue<int>que;
int spfa(){
    memset(dist,0x3f,sizeof(dist));
    memset(pre,-1,sizeof(pre));
    memset(vis,0,sizeof(vis));
    flow[s]=INF,vis[s]=1,dist[s]=0;
    que.push(s);
    while(!que.empty()){
        int x=que.front();que.pop();
        vis[x]=0;
        for(int i=head[x];i!=-1;i=nxt[i]){
            int y=ver[i];
            if(dist[y]>dist[x]+edgec[i] && edgef[i]>0){
                dist[y]=dist[x]+edgec[i];
                pre[y]=i;
                flow[y]=min(flow[x],edgef[i]);
                if(!vis[y]){
                    vis[y]=1;
                    que.push(y);
                }
            }
        }
    }
    return dist[t]!=INF;
}
void EK(){
    int maxflow=0,mincost=0;
    while(spfa()){
        int cur=t;
        while(cur!=s){
            int i=pre[cur];
            edgef[i]-=flow[t];
            edgef[i^1]+=flow[t];
            cur=ver[i^1];
        }
        maxflow+=flow[t];
        mincost+=flow[t]*dist[t];
    }
    cout<<maxflow<<" "<<mincost<<"\n";
}
int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    memset(head,-1,sizeof(head));
    cin>>n>>m;
    s=1,t=n;
    for(int i=2;i<n;i++){
        addedge(i,i+n,0,1);
        
    }
    for(int i=1;i<=m;i++){
        int a,b,c;cin>>a>>b>>c;
        if(a==1)addedge(a,b,c,1);
        else addedge(a+n,b,c,1);
    }
    EK();
    return 0;
}

上一题