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

【题目大意】

Elaxia每天从寝室出发跑到学校,保证寝室编号为1,学校编号为N。 Elaxia的晨跑计划是按周期(包含若干天)进行的,由于他不喜欢走重复的路线,所以在一个周期内,每天的晨跑路线都不会相交(在十字路口处),寝室和学校不算十字路口。表示路口a和路口b之间有条长度为c的街道(单向),求出最长周期的天数和满足最长天数的条件下最短的路程长度。

【思路】

拆点。我们可以将每个路口拆成两个点(i)和(i+N)。由于Ai与Bi之间有长度为C的街道,则在(Ai)和(Bi+N)之间添加一条容量为1,费用为c的边。然后对于每个Ai,添加一条(Ai+n,Ai)的边,容量为1(保证每个路口仅仅经过一次),费用为0的边。最大流即可。

要注意的是1和N不算是路口,所以(1与n+1)(n与2n)之间的边容量为INF。

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<cmath>
  6 #include<queue>
  7 #include<vector>
  8 using namespace std;
  9 const int MAXm=20000+50;
 10 const int MAXn=(200+50)*2;
 11 const int INF=0x7fffffff;
 12 int n,m;//十字路口数和街道数
 13 struct node
 14 {
 15     int to,cap,cost,pos;
 16 };
 17 vector<node> E[MAXn];
 18 int pre[MAXn],preedge[MAXn];
 19
 20 void addedge(int u,int v,int cap,int cost)
 21 {
 22     E[u].push_back((node){v,cap,cost,E[v].size()});
 23     E[v].push_back((node){u,0,-cost,E[u].size()-1});
 24 }
 25
 26 void init()
 27 {
 28     scanf("%d%d",&n,&m);
 29     for (int i=0;i<m;i++)
 30     {
 31         int u,v,cost;
 32         scanf("%d%d%d",&u,&v,&cost);
 33         addedge(u,n+v,1,cost);
 34     }
 35     for (int i=2;i<=n-1;i++) addedge(n+i,i,1,0);
 36     addedge(n+1,1,INF,0);
 37     addedge(2*n,n,INF,0);
 38     //建图的时候不要忘掉了,从1和n+1的边,n和2n的边容量为INF,否则只能跑一天!
 39 }
 40
 41 int SPFA()
 42 {
 43     int dis[MAXn],vis[MAXn];
 44     for (int i=1;i<=2*n;i++) dis[i]=INF;
 45     memset(vis,0,sizeof(vis));
 46     memset(pre,-1,sizeof(pre));
 47     queue<int>que;
 48     que.push(1);
 49     dis[1]=0;
 50     vis[1]=1;
 51     while (!que.empty())
 52     {
 53         int head=que.front();
 54         que.pop();
 55         vis[head]=0;
 56         for (int i=0;i<E[head].size();i++)
 57         {
 58             node& tmp=E[head][i];
 59             if (tmp.cap>0 && dis[tmp.to]>dis[head]+tmp.cost)
 60             {
 61                 dis[tmp.to]=dis[head]+tmp.cost;
 62                 pre[tmp.to]=head;
 63                 preedge[tmp.to]=i;
 64                 if (!vis[tmp.to])
 65                 {
 66                     vis[tmp.to]=1;
 67                     que.push(tmp.to);
 68                 }
 69             }
 70         }
 71     }
 72     if (dis[n]==INF) return 0;//这里是返回到n而不是2n
 73     else return 1;
 74 }
 75
 76 void mcmf()
 77 {
 78     int ans=0,days=0;
 79     while (SPFA())
 80     {
 81         days++;
 82         int flow=INF;
 83         for (int i=n;pre[i]!=-1;i=pre[i])
 84             flow=min(flow,E[pre[i]][preedge[i]].cap);
 85         for (int i=n;pre[i]!=-1;i=pre[i])
 86         {
 87             node& tmp=E[pre[i]][preedge[i]];
 88             tmp.cap-=flow;
 89             E[tmp.to][tmp.pos].cap+=flow;
 90             ans+=flow*tmp.cost;
 91         }
 92     }
 93     cout<<days<<‘ ‘<<ans<<endl;
 94 }
 95
 96 int main()
 97 {
 98     init();
 99     mcmf();
100     return 0;
101 }
时间: 2024-10-05 09:57:05

【费用流】BZOJ1877[SDOI2009]-晨跑的相关文章

BZOJ1877: [SDOI2009]晨跑

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

BZOJ1877 SDOI2009 晨跑 费用流

题意:给定一张有向图,求1到N:1.最多有多少条不相交的路径  2.在第一问的基础上,求所有路径的最小距离和 题解:拆点之后费用流裸题 #include <queue> #include <cstdio> #include <cstring> #include <cstdlib> #include <climits> #include <iostream> #include <algorithm> using namesp

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

【BZOJ1877】晨跑(费用流)

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

1877: [SDOI2009]晨跑

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

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

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

BJOJ1877|SDOI2009晨跑|费用流

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

1877. [SDOI2009]晨跑【费用流】

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

B1877 [SDOI2009]晨跑 费用流

其实之前写过一个板子,但是一点印象都没有,所以今天重写了一下,顺便把这个题当成板子就行了. 其实费用流就是把bfs换成spfa,但是中间有一个原则,就是费用优先,在费用(就是c)上跑spfa,顺便求出流量. 其实理解起来还算简单,就是先spfa找最小费用路径,然后在路径上找能跑的最大流. 题干: Description Elaxia最近迷恋上了空手道,他为自己设定了一套健身计划,比如俯卧撑.仰卧起坐等 等,不过到目前为止,他 坚持下来的只有晨跑. 现在给出一张学校附近的地图,这张地图中包含N个十