题意

链接:https://vjudge.net/problem/HDU-6582

给定一个有向图,可以有重边,每条边上有一个权值表示删掉这条边的代价,问最少花费多少代价能使从s到t节点的最短路径增大?1≤n,m≤10000

思路

容易想到应该是删最短路上的边,最短路可能不止一条,所以使原图1到n的所有最短路不连通即可,这就是最小割呀!选出权值和最小的边使得图不连通,这里是使最短路图不连通。

所以做法就是先建两个图,一个是u->v的有向边,另一个是v->u的有向边,从1跑一下Dijkstra,从n跑一下Dijkstra,我们枚举每条边(u,v),如果这条边是最短路上的边,那么应满足dis1[u]+val(u,v)+dis2[v]=dis1[n],即1到u的最短距离+u到v的距离+v到n的最短距离=1到n的最短距离。

最小割=最大流,跑一下Dinic即可啦。

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define int ll
const int N=1e6+5;
const ll inf=1e16; struct node
{
int p,w;
node(int a,int b)
{
p=a;
w=b;
}
friend bool operator<(node a,node b) //权值小的先出队
{
if(a.w!=b.w) return a.w>b.w;
return a.p>b.p;
}
};
vector <node> eg1[N],eg2[N];
int dis1[N],n,dis2[N];
void add1(int u,int v,int w)
{
eg1[u].push_back(node(v,w));
}
void add2(int u,int v,int w)
{
eg2[u].push_back(node(v,w));
}
void Dijkstra1(int now)
{
for(int i=0; i<=n; i++) dis1[i]=inf;
dis1[now]=0;
priority_queue <node> pq;
pq.push(node(now,dis1[now]));
while(!pq.empty())
{
node f=pq.top();
pq.pop();
for(int i=0; i<eg1[f.p].size(); i++)
{
node t=eg1[f.p][i];
if(dis1[t.p]>t.w+f.w)
{
dis1[t.p]=t.w+f.w;
pq.push(node(t.p,dis1[t.p]));
}
}
}
}
void Dijkstra2(int now)
{
for(int i=0; i<=n; i++) dis2[i]=inf;
dis2[now]=0;
priority_queue <node> pq;
pq.push(node(now,dis2[now]));
while(!pq.empty())
{
node f=pq.top();
pq.pop();
for(int i=0; i<eg2[f.p].size(); i++)
{
node t=eg2[f.p][i];
if(dis2[t.p]>t.w+f.w)
{
dis2[t.p]=t.w+f.w;
pq.push(node(t.p,dis2[t.p]));
}
}
}
}
/***************************************/
int x,y,z,maxflow,deep[N];//deep深度
struct Edge
{
int next,to,dis;
} edge[N];
int num_edge=-1,head[N],cur[N];//cur用于复制head
queue <int> q; void add_edge(int from,int to,int dis,bool flag)
{
edge[++num_edge].next=head[from];
edge[num_edge].to=to;
if (flag) edge[num_edge].dis=dis;//反图的边权为 0
head[from]=num_edge;
} //bfs用来分层
bool bfs(int s,int t)
{
memset(deep,0x7f,sizeof(deep));
while (!q.empty()) q.pop();
for (int i=1; i<=n; i++) cur[i]=head[i];
deep[s]=0;
q.push(s); while (!q.empty())
{
int now=q.front();
q.pop();
for (int i=head[now]; i!=-1; i=edge[i].next)
{
if (deep[edge[i].to]>inf && edge[i].dis)//dis在此处用来做标记 是正图还是返图
{
deep[edge[i].to]=deep[now]+1;
q.push(edge[i].to);
}
}
}
if (deep[t]<inf) return true;
else return false;
} //dfs找增加的流的量
int dfs(int now,int t,int limit)//limit为源点到这个点的路径上的最小边权
{
if (!limit || now==t) return limit; int flow=0,f;
for (int i=cur[now]; i!=-1; i=edge[i].next)
{
cur[now]=i;
if (deep[edge[i].to]==deep[now]+1 && (f=dfs(edge[i].to,t,min(limit,edge[i].dis))))
{
flow+=f;
limit-=f;
edge[i].dis-=f;
edge[i^1].dis+=f;
if (!limit) break;
}
}
return flow;
} void Dinic(int s,int t)
{
while (bfs(s,t))
maxflow+=dfs(s,t,inf);
}
/***********************************************/
signed main()
{
int u,v,m,w,t;
scanf("%lld",&t);
while(t--)
{ scanf("%lld%lld",&n,&m);
for(int i=0; i<=n; i++) eg1[i].clear(),eg2[i].clear();
for(int i=0; i<m; i++)
{
scanf("%lld%lld%lld",&u,&v,&w);
add1(u,v,w);
add2(v,u,w);
}
Dijkstra1(1);
Dijkstra2(n);
memset(head,-1,sizeof(head));
for(int i=1; i<=n; i++)
{
int sz=eg1[i].size();
for(int j=0; j<sz; j++)
{
if(dis1[i]+eg1[i][j].w+dis2[eg1[i][j].p]==dis1[n])
{
add_edge(i,eg1[i][j].p,eg1[i][j].w,1);
add_edge(eg1[i][j].p,i,eg1[i][j].w,0);
}
}
}
maxflow=0;
Dinic(1,n);
printf("%lld\n",maxflow);
}
return 0;
}

最新文章

  1. hammerJs-v2.0.4详解
  2. 将Excel数据导入数据库
  3. PDO vs. MySQLi 选择哪一个?(PDO vs. MySQLi: Which Should You Use?)-转载
  4. App 即时通讯 SDK
  5. 配置WebSite的IIS时遇到的问题与解决方法
  6. ytu 2463:给小鼠补充代码(DFS 深度优先搜索)
  7. CompressFilterAttribute 文件压缩特性
  8. HTML DOM 创建与修改
  9. linux-sfdisk 使用方法
  10. C语言变参函数的编写
  11. 如何使用UDP进行跨网段广播(转)
  12. HDU1754-I Hate It-线段树
  13. 第二章 Linux目录学习
  14. 前后端分离djangorestframework—— 在线视频平台接入第三方加密防盗录视频
  15. vsphere client/web client 开启ESXi SSH服务
  16. CSS初步学习
  17. windows文件服务器的磁盘空间挂载在linux目录下使用
  18. vuex的数据交互
  19. JavaEE学习总结(十三)—JavaWeb、JSP、Servlet与DVD管理系统
  20. linux command&gt;file 2&gt;&amp;1 &amp; 命令详解

热门文章

  1. Flutter 基础控件
  2. R-3 t分布--t置信区间--t检验
  3. LG4158 「SCOI2009」粉刷匠 线性DP
  4. 关于scanf的一些知识
  5. vue框架学习笔记(vue入门篇)
  6. spring cloud 2.x版本 Sleuth+Zipkin分布式链路追踪
  7. Vue ---- 组件文件分析 组件生命周期钩子 路由 跳转 传参
  8. IT兄弟连 HTML5教程 介绍HTML5给你认识 习题
  9. IT兄弟连 Java语法教程 流程控制语句 经典案例
  10. 07-selenium、PhantomJS(无头浏览器)