【最短路】【最大流】bzoj3931 [CQOI2015]网络吞吐量

跑出最短路图,然后把结点拆点跑最大流。

#include<cstdio>
#include<queue>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define M 100001
#define INF 2147483647
#define N 501
typedef long long ll;
namespace Net
{
	int v[M<<1],next[M<<1],first[N<<1],en,cap[M<<1];
	queue<int>q;
	void AddEdge(int U,int V,int Cap)
	  {
	  	v[en]=V; cap[en]=Cap; next[en]=first[U]; first[U]=en++;
	  	v[en]=U; next[en]=first[V]; first[V]=en++;
	  }
	int S,T,n;
	int d[N<<1],cur[N<<1];
	int bfs()
	  {
	  	memset(d,-1,sizeof(int)*(n+1));
	  	d[S]=0;
	  	q.push(S);
	  	while(!q.empty())
	  	  {
	  	  	int U=q.front(); q.pop();
	  	  	for(int i=first[U];i!=-1;i=next[i])
	  	  	  if(cap[i]&&d[v[i]]==-1)
	  	  	    {
	  	  	      d[v[i]]=d[U]+1;
	  	  	      q.push(v[i]);
	  	  	    }
	  	  }
	  	return d[T]!=-1;
	  }
	int dfs(int U,int a)
	  {
	  	if(U==T||(!a))
	  	  return a;
	  	int f,Flow=0;
	  	for(int &i=cur[U];i!=-1;i=next[i])
	  	  if(d[v[i]]==d[U]+1&&(f=dfs(v[i],min(a,cap[i]))))
	  	    {
	  	      cap[i]-=f; cap[i^1]+=f;
	  	      Flow+=f; a-=f;
	  	      if(!a) break;
	  	    }
	  	if(!Flow) d[U]=-1;
	  	return Flow;
	  }
	ll MaxFlow()
	  {
	  	ll Flow=0;
		int tmp;
	  	while(bfs())
	  	  {
	  	  	memcpy(cur,first,sizeof(int)*(n+1));
	  	  	while(tmp=dfs(S,INF))
	  	  	  Flow+=(ll)tmp;
	  	  }
	  	return Flow;
	  }
};
namespace SP
{
	int n,m;
	queue<int>q;
	int v[M<<1],w[M<<1],next[M<<1],first[N],en;
	void AddEdge(int U,int V,int W)
	  {
	  	v[++en]=V;
		w[en]=W;
		next[en]=first[U];
		first[U]=en;
	  }
	ll d[N];
	bool inq[N];
	void spfa(int S)
	  {
	  	for(int i=1;i<=n;++i)
	  	  d[i]=INF;
	  	d[S]=0;
	  	q.push(S);
	  	inq[S]=1;
	  	while(!q.empty())
	  	  {
	  	  	int U=q.front();
	  	  	for(int i=first[U];i;i=next[i])
	  	  	  if(d[U]+(ll)w[i]<d[v[i]])
	  	  	    {
	  	  	      d[v[i]]=d[U]+(ll)w[i];
	  	  	      if(!inq[v[i]])
	  	  	        {
	  	  	          inq[v[i]]=1;
	  	  	          q.push(v[i]);
	  	  	        }
	  	  	    }
	  	  	q.pop(); inq[U]=0;
	  	  }
	  }
};
int Map(int x,bool op)
{
	if(x==Net::S||x==Net::T)
	  return x;
	return ((!op)?((x<<1)-2):((x<<1)-1));
}
int main()
{
	int x,y,z;
	scanf("%d%d",&SP::n,&SP::m);
	for(int i=1;i<=SP::m;++i)
	  {
	  	scanf("%d%d%d",&x,&y,&z);
	  	SP::AddEdge(x,y,z);
	  	SP::AddEdge(y,x,z);
	  }
	SP::spfa(1);
	Net::S=1;
	Net::T=2*SP::n-2;
	Net::n=2*SP::n-2;
	memset(Net::first,-1,sizeof(int)*(Net::n+1));
	for(int i=1;i<=SP::en;i+=2)
	  {
	  	if(SP::d[SP::v[i+1]]+(ll)SP::w[i]==SP::d[SP::v[i]])
	      Net::AddEdge(Map(SP::v[i+1],1),Map(SP::v[i],0),INF);
	    if(SP::d[SP::v[i]]+(ll)SP::w[i]==SP::d[SP::v[i+1]])
	      Net::AddEdge(Map(SP::v[i],1),Map(SP::v[i+1],0),INF);
	  }
	scanf("%d",&x);
	for(int i=2;i<SP::n;++i)
	  {
	  	scanf("%d",&x);
	  	Net::AddEdge(Map(i,0),Map(i,1),x);
	  }
	scanf("%d",&x);
	cout<<Net::MaxFlow()<<endl;
	return 0;
}
时间: 2024-08-07 16:56:06

【最短路】【最大流】bzoj3931 [CQOI2015]网络吞吐量的相关文章

bzoj3931: [CQOI2015]网络吞吐量

将最短路图找出来,跑maxflow即可.有注意到数据范围.然后输出的时候%dWA了三次QAQ... #include<cstdio> #include<cstring> #include<iostream> #include<queue> #include<algorithm> using namespace std; #define rep(i,n) for(int i=1;i<=n;i++) #define ll long long #

[BZOJ3931][CQOI2015]网络吞吐量(spfa+最大流)

题目描述 传送门 题解 求出最短路径图之后拆点跑最大流. 判断一条边在最短路图上:dis[edge[i].x]+redis[edge[i].y]+edge[i].w==dis[n]或dis[edge[i].y]+redis[edge[i].x]+edge[i].w==dis[n],其中dis和redis都是单源最短路,源分别为1和n 代码 #include<algorithm> #include<iostream> #include<cstring> #include&

BZOJ3931 [CQOI2015]网络吞吐量(最大流)

没啥好说的,有写过类似的,就是预处理出最短路上的边建容量网络. 1 #include<cstdio> 2 #include<cstring> 3 #include<queue> 4 #include<algorithm> 5 using namespace std; 6 #define INF (1LL<<60) 7 #define MAXN 1111 8 #define MAXM 1111*1111*2 9 10 struct Edge{ 11

BZOJ 3931: [CQOI2015]网络吞吐量( 最短路 + 最大流 )

最短路 + 最大流 , 没什么好说的... 因为long long WA 了两次.... ------------------------------------------------------------------------- #include<cstdio> #include<cstring> #include<algorithm> #include<queue> #include<vector> #include<iostre

【BZOJ-3931】网络吞吐量 最短路 + 最大流

3931: [CQOI2015]网络吞吐量 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1228  Solved: 524[Submit][Status][Discuss] Description 路由是指通过计算机网络把信息从源地址传输到目的地址的活动,也是计算机网络设计中的重点和难点.网络中实现路由转发的硬件设备称为路由器.为了使数据包最快的到达目的地,路由器需要选择最优的路径转发数据包.例如在常用的路由算法OSPF(开放式最短路径优先)中

bzoj 3931: [CQOI2015]网络吞吐量(最短路+网络流)

3931: [CQOI2015]网络吞吐量 Time Limit: 10 Sec  Memory Limit: 512 MB Submit: 1194  Solved: 508 [Submit][Status][Discuss] Description 路由是指通过计算机网络把信息从源地址传输到目的地址的活动,也是计算机网络设计中的重点和难点.网络中实现路由转发的硬件设备称为路由器.为了使数据包最快的到达目的地,路由器需要选择最优的路径转发数据包.例如在常用的路由算法OSPF(开放式最短路径优先

BZOJ 3931: [CQOI2015]网络吞吐量 最大流

3931: [CQOI2015]网络吞吐量 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/problem.php?id=3931 Description 路由是指通过计算机网络把信息从源地址传输到目的地址的活动,也是计算机网络设计中的重点和难点.网络中实现路由转发的硬件设备称为路由器.为了使数据包最快的到达目的地,路由器需要选择最优的路径转发数据包.例如在常用的路由算法OSPF(开放式最短

BZOJ 3931: [CQOI2015]网络吞吐量

3931: [CQOI2015]网络吞吐量 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1555  Solved: 637[Submit][Status][Discuss] Description 路由是指通过计算机网络把信息从源地址传输到目的地址的活动,也是计算机网络设计中的重点和难点.网络中实现路由转发的硬件设备称为路由器.为了使数据包最快的到达目的地,路由器需要选择最优的路径转发数据包.例如在常用的路由算法OSPF(开放式最短路径优先)中

P3171 [CQOI2015]网络吞吐量

P3171 [CQOI2015]网络吞吐量https://www.luogu.org/problemnew/show/P3171 题目描述 路由是指通过计算机网络把信息从源地址传输到目的地址的活动,也是计算机网络设计中的重点和难点.网络中实现路由转发的硬件设备称为路由器.为了使数据包最快的到达目的地,路由器需要选择最优的路径转发数据包.例如在常用的路由算法OSPF(开放式最短路径优先)中,路由器会使用经典的Dijkstra算法计算最短路径,然后尽量沿最短路径转发数据包.现在,若已知一个计算机网络