NC20328. [SDOI2009]晨跑
描述
输入描述
第一行:两个数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; }