博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
P2153 [SDOI2009]晨跑
阅读量:6817 次
发布时间:2019-06-26

本文共 1479 字,大约阅读时间需要 4 分钟。

这里写图片描述

题目要求不能通过相同的点,限制点,和蜥蜴那个题类似,将每个点拆成两个点,中间连一条边,因为每个点只能通过一次,所以边的流量为1

因为起点和汇点不算十字路口,所以不用拆,在与1号点直接相连的点和1号点之间连一条流量为1的边,与n号点相连的点一样如此处理,然后用最小费用最大流就可以了。最大流即为天数,最小费用即为总路程。
需要注意的问题是构建cost的反向边。

代码

#include
#include
#include
#include
#include
#include
#include
#define INF 2139062143using namespace std;int n,m;int pre[409],f[409];int cost[409][409],cap[409][409];int mflow=0,mcost=0;int flow[409],dis[409];int bfs(int s,int t){ queue
q; while(!q.empty()) q.pop(); memset(pre,-1,sizeof(pre)); memset(dis,127,sizeof(dis)); memset(f,0,sizeof(f)); q.push(s); pre[s]=0; flow[s]=INF; dis[s]=0; f[s]=1; while(!q.empty()) { int k=q.front(); q.pop(); f[k]=0; for(int i=1;i<2*n;i++) { if(cap[k][i]>0&&dis[i]>dis[k]+cost[k][i]) { dis[i]=dis[k]+cost[k][i]; flow[i]=min(flow[k],cap[k][i]); pre[i]=k; if(!f[i]) q.push(i),f[i]=1; } } } if(pre[t]==-1) return -1; return flow[t]; }void maxflow(int s,int t){ int d; while(1) { d=bfs(s,t); if(d==-1) return; int k=t; while(k!=s) { cap[pre[k]][k]-=d; cap[k][pre[k]]+=d; k=pre[k]; } mflow+=d; mcost+=d*dis[t]; } return;}int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) { int a,b,c; scanf("%d%d%d",&a,&b,&c); int cu; if(a==1) cu=1; else cu=a+n; cap[cu][b]=1; cost[cu][b]=c; cost[b][cu]=-c;//反向边 } for(int i=2;i<=n-1;i++) cap[i][i+n]=1; maxflow(1,n); printf("%d %d",mflow,mcost); return 0;}

转载于:https://www.cnblogs.com/dfsac/p/6819723.html

你可能感兴趣的文章
【项目实战】多线程环境下正确创建单例
查看>>
linux centos 7 nodejs 的安装
查看>>
mssqlserver分区表的左值与右值
查看>>
推荐系统
查看>>
HoloLens | 世界的每一次变化,其实都提前打好了招呼
查看>>
seq命令
查看>>
线性表接口的实现_Java
查看>>
利用安卓手机搭建WEB服务器
查看>>
小巧玲珑:机器学习届快刀XGBoost的介绍和使用
查看>>
intellij开发安卓与genymotion配合
查看>>
jmeter大神博客笔记
查看>>
java.lang.NoClassDefFoundError: javax/annotation/Priority
查看>>
skimage的安装,scikit-image
查看>>
springmvc-mvc:resource标签使用
查看>>
如何理解php的依赖注入
查看>>
洛谷P2084 进制转换
查看>>
直接上手从项目中学习很重要
查看>>
[转载]非常量引用的初始值必须为左值的问题
查看>>
C# 线程池执行操作例子
查看>>
duubo开发时直连(不需要注册中心)
查看>>