原题传送门

一眼应该就能看出是费用流

因为每个交叉路口只能通过一次,所以我们进行拆点,连一条流量为1费用为0的边

再按照题目给的边(是单向边)建图

跑一下MCMF就行了

拆点很套路的~

#include <bits/stdc++.h>
#define N 205
#define M 20005
#define inf (1<<30)
#define getchar nc
using namespace std;
inline char nc(){
static char buf[100000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline int read()
{
register int x=0,f=1;register char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
return x*f;
}
inline void write(register int x)
{
if(!x)putchar('0');if(x<0)x=-x,putchar('-');
static int sta[20];register int tot=0;
while(x)sta[tot++]=x%10,x/=10;
while(tot)putchar(sta[--tot]+48);
}
inline int Min(register int a,register int b)
{
return a<b?a:b;
}
struct node{
int to,next,v,c;
}e[(M<<2)+(N<<1)];
int head[N<<1],cnt=1;
inline void add(register int u,register int v,register int val,register int cost)
{
e[++cnt]=(node){v,head[u],val,cost};
head[u]=cnt;
}
int n,m,s,t,maxflow=0,mincost=0;
int vis[N<<1],dist[N<<1];
inline bool spfa()
{
memset(vis,0,sizeof(vis));
memset(dist,0x3f,sizeof(dist));
dist[s]=0;
vis[s]=1;
queue<int> q;
q.push(s);
while(!q.empty())
{
int u=q.front();
q.pop();
vis[u]=0;
for(register int i=head[u];i;i=e[i].next)
{
int v=e[i].to;
if(dist[v]>dist[u]+e[i].c&&e[i].v)
{
dist[v]=dist[u]+e[i].c;
if(vis[v]==0)
{
q.push(v);
vis[v]=1;
}
}
}
}
return dist[t]!=0x3f3f3f3f;
}
inline int dfs(register int u,register int flow)
{
if(u==t)
{
vis[t]=1;
maxflow+=flow;
return flow;
}
int used=0;
vis[u]=1;
for(register int i=head[u];i;i=e[i].next)
{
int v=e[i].to;
if((vis[v]==0||v==t)&&e[i].v&&dist[v]==dist[u]+e[i].c)
{
int tmp=dfs(v,Min(e[i].v,flow-used));
if(tmp)
{
mincost+=e[i].c*tmp;
used+=tmp;
e[i].v-=tmp;
e[i^1].v+=tmp;
}
if(used==flow)
return used;
}
}
return used;
}
inline void MCMF()
{
while(spfa())
{
vis[t]=1;
while(vis[t])
{
memset(vis,0,sizeof(vis));
dfs(s,inf);
}
}
}
int main()
{
n=read(),m=read();
s=1,t=n;
for(register int i=2;i<n;++i)
add(i,i+n,1,0),add(i+n,i,0,0);
for(register int i=1;i<=m;++i)
{
int u=read(),v=read(),cost=read();
if(u==1)
add(u,v,1,cost),add(v,u,0,-cost);
else if(v==n)
add(u+n,v,1,cost),add(v,u+n,0,-cost);
else
add(u+n,v,1,cost),add(v,u+n,0,-cost);
}
MCMF();
write(maxflow),putchar(' '),write(mincost);
return 0;
}

最新文章

  1. Git异常:fatal: V1.0 cannot be resolved to branch.
  2. HDU 2586
  3. UIWebView用法详解及代码分享
  4. C语言中的关键字
  5. offsetParent、offsetTop、offsetLeft、offsetWidth、offsetHeight
  6. (转载)Flash Builder和flashdevelop 常用快捷键
  7. Java Socket 编程指南
  8. mysql乱码配置
  9. LeetCode之“散列表”:Valid Sudoku
  10. PHP7 ?:和??的区别
  11. 以Attribute加上Header验证
  12. MVC Filter
  13. 移动H5开发入门教程:12点webAPP前端开发经验
  14. openstack将本地实例迁移至ceph存储中
  15. Linux基础综合练习
  16. 用Eclipse进行远程Debug代码
  17. LintCode-373.奇偶分割数组
  18. Bazinga 字符串HASH 这题不能裸HASH 要优化 毒瘤题
  19. Python Flask SQLALchemy基础知识
  20. window下安装Node.js NPM

热门文章

  1. Chrome Google浏览器下载
  2. 第三天 Linux简单命令
  3. weapp-mobx
  4. 每个JavaScript程序员都需要知道的5个数组方法
  5. juqery 回车事件 回车操作 回车搜索
  6. Java 递归获取一个路径下的所有文件,文件夹名称
  7. SQLSERVER CTE表 row_number()字段 BUG
  8. Codeforces 1099 - A/B/C/D/E/F - (Done)
  9. Tensorflow 的saved_model模块学习
  10. [yum] yum加速