zoukankan      html  css  js  c++  java
  • 【最短路】【最大流】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;
    }
  • 相关阅读:
    MySQL GTID复制Slave跳过错误事务Id以及复制排错问题总结
    Git基础命令整理
    原创-公司项目部署交付环境预检查shell脚本
    解决SecureCRT超时自动断开的问题
    Linux设置显示中文和设置字体
    高等代数4 线性方程组
    高等代数3 行列式
    高等代数2 向量组
    高等代数1 矩阵
    离散数学4 组合数学
  • 原文地址:https://www.cnblogs.com/autsky-jadek/p/4423923.html
Copyright © 2011-2022 走看看