[bzoj1877]晨跑

很显然是网络流,对于点的限制,拆点建流量为1的边,之后跑最小费用最大流即可(由此很显然可以发现原图边的流量也只需要1)

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define N 405
 4 struct ji{
 5     int nex,to,len,cost;
 6 }edge[N*N];
 7 queue<int>q;
 8 int E,n,m,x,y,z,ans1,ans2,head[N],d[N],from[N],vis[N];
 9 void add(int x,int y,int z,int w){
10     edge[E].nex=head[x];
11     edge[E].to=y;
12     edge[E].len=z;
13     edge[E].cost=w;
14     head[x]=E++;
15     if (E&1)add(y,x,0,-w);
16 }
17 bool spfa(){
18     memset(d,0x3f,sizeof(d));
19     memset(vis,0,sizeof(vis));
20     q.push(1);
21     d[1]=0;
22     while (!q.empty()){
23         int k=q.front();
24         q.pop();
25         vis[k]=0;
26         for(int i=head[k];i!=-1;i=edge[i].nex){
27             int v=edge[i].to;
28             if ((edge[i].len)&&(d[v]>d[k]+edge[i].cost)){
29                 d[v]=d[k]+edge[i].cost;
30                 from[v]=i;
31                 if (!vis[v]){
32                     vis[v]=1;
33                     q.push(v);
34                 }
35             }
36         }
37     }
38     return d[2*n]<0x3f3f3f3f;
39 }
40 int main(){
41     scanf("%d%d",&n,&m);
42     memset(head,-1,sizeof(head));
43     for(int i=1;i<=m;i++){
44         scanf("%d%d%d",&x,&y,&z);
45         add(x,y+n,1,z);
46     }
47     for(int i=1;i<=n;i++)add(i+n,i,1,0);
48     ans1=ans2=0;
49     while (spfa()){
50         ans1++;
51         ans2+=d[2*n];
52         for(int i=2*n;i>1;i=edge[from[i]^1].to){
53             edge[from[i]].len--;
54             edge[from[i]^1].len++;
55         }
56     }
57     printf("%d %d",ans1,ans2);
58 } 

原文地址:https://www.cnblogs.com/PYWBKTDA/p/11830699.html

时间: 2024-11-05 19:03:44

[bzoj1877]晨跑的相关文章

[SDOI2009][BZOJ1877] 晨跑

1877: [SDOI2009]晨跑 Time Limit: 4 Sec  Memory Limit: 64 MBSubmit: 1393  Solved: 729[Submit][Status][Discuss] Description Elaxia最近迷恋上了空手道,他为自己设定了一套健身计划,比如俯卧撑.仰卧起坐等 等,不过到目前为止,他坚持下来的只有晨跑. 现在给出一张学校附近的地图,这张地图中包含N个十字路口和M条街道,Elaxia只能从 一个十字路口跑向另外一个十字路口,街道之间只在

[SDOI2009][bzoj1877] 晨跑 [费用流]

题面: 传送门 思路: 一个点只能走一回,路径不能相交...... 显然可以转化为网络流的决策来做 我们构建一个网络,令其最大流等于最大的跑步天数即可 怎么构造呢? 对于每个点只能走一次的限制,可以考虑拆点,将每个点(除了起点和终点)拆成两个,中间连一条容量为1的边,就可以了 同时,因为要求走的距离最短,那么给每一条原图中的边赋一个费用,把最大流改成费用流即可 这道题有一个值得深思的地方:是题目中的哪个点让你想到要用网络流而不是别的算法来做的? 这道题我实际上是抱着"网络流那么厉害,说不定就做得

BZOJ1877: [SDOI2009]晨跑

1877: [SDOI2009]晨跑 Time Limit: 4 Sec  Memory Limit: 64 MBSubmit: 1024  Solved: 540[Submit][Status] Description Elaxia最近迷恋上了空手道,他为自己设定了一套健身计划,比如俯卧撑.仰卧起坐等 等,不过到目前为止,他坚持下来的只有晨跑. 现在给出一张学校附近的地图,这张地图中包含N个十字路口和M条街道,Elaxia只能从 一个十字路口跑向另外一个十字路口,街道之间只在十字路口处相交.E

【BZOJ1877】晨跑(费用流)

[BZOJ1877]晨跑(费用流) 题面 Description Elaxia最近迷恋上了空手道,他为自己设定了一套健身计划,比如俯卧撑.仰卧起坐等 等,不过到目前为止,他 坚持下来的只有晨跑. 现在给出一张学校附近的地图,这张地图中包含N个十字路口和M条街道,Elaxia只能从 一 个十字路口跑向另外一个十字路口,街道之间只在十字路口处相交.Elaxia每天从寝室出发 跑到学校,保证寝室 编号为1,学校编号为N. Elaxia的晨跑计划是按周期(包含若干天)进行的,由于他不喜欢走重复的路线,所

【费用流】BZOJ1877[SDOI2009]-晨跑

[题目大意] Elaxia每天从寝室出发跑到学校,保证寝室编号为1,学校编号为N. Elaxia的晨跑计划是按周期(包含若干天)进行的,由于他不喜欢走重复的路线,所以在一个周期内,每天的晨跑路线都不会相交(在十字路口处),寝室和学校不算十字路口.表示路口a和路口b之间有条长度为c的街道(单向),求出最长周期的天数和满足最长天数的条件下最短的路程长度. [思路] 拆点.我们可以将每个路口拆成两个点(i)和(i+N).由于Ai与Bi之间有长度为C的街道,则在(Ai)和(Bi+N)之间添加一条容量为1

BZOJ1877:[SDOI2009]晨跑——题解

http://www.lydsy.com/JudgeOnline/problem.php?id=1877 https://www.luogu.org/problemnew/show/P2153 Elaxia最近迷恋上了空手道,他为自己设定了一套健身计划,比如俯卧撑.仰卧起坐等 等,不过到目前为止,他坚持下来的只有晨跑. 现在给出一张学校附近的地图,这张地图中包含N个十字路口和M条街道,Elaxia只能从 一个十字路口跑向另外一个十字路口,街道之间只在十字路口处相交.Elaxia每天从寝室出发 跑

BZOJ 1877:[SDOI2009]晨跑(最小费用最大流)

晨跑DescriptionElaxia最近迷恋上了空手道,他为自己设定了一套健身计划,比如俯卧撑.仰卧起坐等 等,不过到目前为止,他坚持下来的只有晨跑. 现在给出一张学校附近的地图,这张地图中包含N个十字路口和M条街道,Elaxia只能从 一个十字路口跑向另外一个十字路口,街道之间只在十字路口处相交.Elaxia每天从寝室出发 跑到学校,保证寝室编号为1,学校编号为N. Elaxia的晨跑计划是按周期(包含若干天)进行的,由于他不喜欢走重复的路线,所以 在一个周期内,每天的晨跑路线都不会相交(在

[SDOI2009] 晨跑

★★☆   输入文件:run.in   输出文件:run.out   简单对比 时间限制:2 s   内存限制:128 MB Elaxia最近迷恋上了空手道,他为自己设定了一套健身计划,比如俯卧撑.仰卧起坐等等,不过到目前为止,他坚持下来的只有晨跑. 现在给出一张学校附近的地图,这张地图中包含N个十字路口和M条街道,Elaxia只能从一个十字路口跑向另外一个十字路口,街道之间只在十字路口处相交.Elaxia每天从寝室出发跑到学校,保证寝室编号为1,学校编号为N. Elaxia的晨跑计划是按周期(

BZOJ 1877: [SDOI2009]晨跑( 最小费用最大流 )

裸的费用流...拆点, 流量限制为1, 最后的流量和费用即答案. ---------------------------------------------------------------------- #include<bits/stdc++.h> using namespace std; const int maxn = 409; const int INF = 1 << 30; struct edge { int to, cap, cost; edge *next, *r