Dinic

最大流

#include<bits/stdc++.h>
using namespace std;
#define N 210
#define M 5010
#define INF 0x3f3f3f3f
int n,m,S,T;
vector<int>head,to,nxt,val;
void join(int u,int v,int w)
{
	nxt.push_back(head[u]);
	head[u]=to.size();
	to.push_back(v);
	val.push_back(w);
}
int dep[N],cur[N];
queue<int>q;
bool bfs(int s,int t)
{
	memset(dep,0,sizeof(dep));
	dep[s]=1;
	while(!q.empty()) q.pop();
	q.push(s);
	while(!q.empty())
	{
		int u=q.front();q.pop();
		for(int i=head[u];i!=-1;i=nxt[i])
		{
			if(val[i]&&!dep[to[i]])
			{
				dep[to[i]]=dep[u]+1;
				q.push(to[i]);
			}
		}
	}
	return dep[t];
}
int dfs(int u,int t,int f)
{
	if(u==t) return f;
	int i;
	for(int i=cur[u];i!=-1;i=nxt[i])
	{
		cur[u]=i; 
		if(val[i]&&dep[to[i]]==dep[u]+1)
		{
			int tmp=dfs(to[i],t,min(f,val[i]));
			if(tmp>0)
			{
				val[i]-=tmp;
				val[i^1]+=tmp;
				return tmp;
			}
		}
	}
	return 0;
}
long long dinic()
{
	long long res=0;
	while(bfs(S,T))
	{
		for(int i=0;i<=head.size();++i) cur[i]=head[i];
		while(int d=dfs(S,T,INF))
		{
			res+=d;
		}
	}
	return res;
}
int main()
{
	scanf("%d%d%d%d",&n,&m,&S,&T);
	head.resize(n+1,-1);
	for(int i=1;i<=m;++i)
	{
		int u,v,w;
		scanf("%d%d%d",&u,&v,&w);
		join(u,v,w);
		join(v,u,0);
	}
	long long ans=dinic();
	printf("%lld",ans);
	return 0;
}

费用流

然后另外注意,最大费用最大流就是对于最小费用最大流把边上的费用取相反数,然后答案也取相反数就行。

#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 5010
#define M 1000010
int n,m,S,T;
int dis[N],cur[M];
bool vis[N];
vector<int>head,nxt,to,val,cost;
int ret=0;
void join(int u,int v,int w,int c)
{
    nxt.push_back(head[u]);
    head[u]=to.size();
    to.push_back(v);
    val.push_back(w);
    cost.push_back(c);
}
queue<int>q;
bool spfa(int s,int t)
{
    memset(dis,INF,sizeof(dis));
    memset(vis,0,sizeof(vis));
    vis[s]=1;q.push(s);dis[s]=0;
    while(!q.empty())
    {
    	int u=q.front();q.pop();vis[u]=0;
    	for(int i=head[u];i!=-1;i=nxt[i])
    	{
    		if(val[i]&&dis[to[i]]>dis[u]+cost[i])
    		{
    			dis[to[i]]=dis[u]+cost[i];
    			if(!vis[to[i]])
    			{
    				vis[to[i]]=1;
    				q.push(to[i]);
				}
			} 
		}
	}
	return dis[t]!=INF;
} 
int dfs(int u,int t,int f)
{
	if(u==S) memset(vis,0,sizeof(vis));
    if(u==t) return f;
    vis[u]=1;
    for(int i=cur[u];i!=-1;i=nxt[i])
    {
		cur[u]=i;
        if(!vis[to[i]]&&val[i]!=0&&dis[to[i]]==dis[u]+cost[i])
        {
            int tmp=dfs(to[i],t,min(f,val[i]));
            if(tmp>0)
            {
            	ret+=tmp*cost[i];
                val[i]-=tmp;
                val[i^1]+=tmp;
                return tmp;
            } 
        }
    }
    vis[u]=0;
    return 0;
}
int mcmf()
{
    int ans=0;
    while(spfa(S,T))
    {
        for(int i=0;i<=to.size();++i) cur[i]=head[i];
        while(int d=dfs(S,T,INF))
        {
            ans+=d;
        }
    }
    return ans;
}
int anss=0;
int main()
{
	scanf("%d%d%d%d",&n,&m,&S,&T);
	head.resize(2*m+2,-1);
	for(int i=1;i<=m;++i)
	{
		int u,v,w,c;
		scanf("%d%d%d%d",&u,&v,&w,&c);
		join(u,v,w,c);
		join(v,u,0,-c);
	}
	anss=mcmf();
	printf("%d %d",anss,ret);
    return 0;
}
posted @ 2022-02-24 11:33  cbdsopa  阅读(64)  评论(0编辑  收藏  举报