求出最短路后找出可能在最短路上的边,显然割完边后我们需要让图中这样的边无法构成1到n的路径,最小割即可,非常板子。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
#define N 510
#define M 250000
#define inf 2000000000
int n,m,p[N],d[N],t=;
bool flag[N];
struct data{int to,nxt,len,cost;
}edge[M];
void addedge(int x,int y,int z,int c){t++;edge[t].to=y,edge[t].nxt=p[x],edge[t].len=z,edge[t].cost=c,p[x]=t;}
namespace flow
{
int cur[N],q[N],d[N],ans=;
struct data{int to,nxt,cap,flow;
}edge[M];
void addedge(int x,int y,int z)
{
t++;edge[t].to=y,edge[t].nxt=p[x],edge[t].cap=z,edge[t].flow=,p[x]=t;
t++;edge[t].to=x,edge[t].nxt=p[y],edge[t].cap=,edge[t].flow=,p[y]=t;
}
bool bfs()
{
memset(d,,sizeof(d));d[]=;
int head=,tail=;q[]=;
do
{
int x=q[++head];
for (int i=p[x];~i;i=edge[i].nxt)
if (d[edge[i].to]==-&&edge[i].flow<edge[i].cap)
{
d[edge[i].to]=d[x]+;
q[++tail]=edge[i].to;
}
}while (head<tail);
return ~d[n];
}
int work(int k,int f)
{
if (k==n) return f;
int used=;
for (int i=cur[k];~i;i=edge[i].nxt)
if (d[k]+==d[edge[i].to])
{
int w=work(edge[i].to,min(f-used,edge[i].cap-edge[i].flow));
edge[i].flow+=w,edge[i^].flow-=w;
if (edge[i].flow<edge[i].cap) cur[k]=i;
used+=w;if (used==f) return f;
}
if (used==) d[k]=-;
return used;
}
void dinic()
{
while (bfs())
{
memcpy(cur,p,sizeof(p));
ans+=work(,inf);
}
cout<<ans;
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("bzoj1266.in","r",stdin);
freopen("bzoj1266.out","w",stdout);
const char LL[]="%I64d\n";
#else
const char LL[]="%lld\n";
#endif
n=read(),m=read();
for (int i=;i<=m;i++)
{
int x=read(),y=read(),z=read(),c=read();
addedge(x,y,z,c);addedge(y,x,z,c);
}
memset(d,,sizeof(d));d[]=;
for (int i=;i<=n;i++)
{
int mn=;
for (int j=;j<=n;j++)
if (!flag[j]&&d[j]<d[mn]) mn=j;
flag[mn]=;
for (int j=p[mn];j;j=edge[j].nxt)
if (d[mn]+edge[j].len<d[edge[j].to]) d[edge[j].to]=d[mn]+edge[j].len;
}
cout<<d[n]<<endl;
t=-;memset(p,,sizeof(p));
for (int i=;i<=m;i++)
{
if (d[edge[i<<].to]+edge[i<<].len==d[edge[i*-].to])
flow::addedge(edge[i<<].to,edge[i*-].to,edge[i<<].cost);
if (d[edge[i*-].to]+edge[i*-].len==d[edge[i<<].to])
flow::addedge(edge[i*-].to,edge[i<<].to,edge[i<<].cost);
}
flow::dinic();
return ;
}

最新文章

  1. Android—定位
  2. 浅谈Android下的Bitmap之大Bitmap加载
  3. 一次dell R420 电源故障引发的“血案”
  4. mysql:查询结果添加序列号
  5. Knockout.Js案例二Working With Lists And Collections
  6. iOS开发中几个重要的方法
  7. 让DIV水平和垂直居中的几种方法
  8. SpringMVC实现上传和下载
  9. [BZOJ3343]教主的魔法
  10. vmware安装linux.iso
  11. 长城坑爹宽带,劫持用户DNS赚取购物返利
  12. 3、WPF学习之-布局
  13. eclipse下maven插件的安装
  14. 2进制,16进制,BCD,ascii,序列化对象相互转换
  15. JS(一)
  16. Device Mapper Multipath(DM-Multipath)
  17. win10无法新建文件夹怎么办 win10右键新建菜单设置方法
  18. android学习经常使用的数据文件夹
  19. Android项目--Json解析
  20. Class.forName()

热门文章

  1. Ubuntu 上安装QTAV第三方视频库
  2. 树莓派学习笔记(7):利用bypy实现树莓派NAS同步百度云
  3. 浅谈UI自动化测试
  4. Zephyr的Logging
  5. angularjs springMVC 交互
  6. LiveCharts文档-4基本绘图-3其他
  7. MiniProfiler工具介绍(监控EF生成的SQL语句)--EF,迷你监控器,哈哈哈
  8. ML.NET 示例:二元分类之用户评论的情绪分析
  9. iOS开发简记(3):tips提示
  10. Ionic 入门与实战之第二章第一节:Ionic 环境搭建之开发环境配置