• 【bzoj1797】 Ahoi2009—Mincut 最小割


    http://www.lydsy.com/JudgeOnline/problem.php?id=1797 (题目链接)

    题意

      求一条边是否可能在一个最小割集中,以及这条边是否一定在最小割集中。

    Solution

      DaD3zZ大爷

      跑完最大流以后,在残余网络上跑tarjan求出所有SCC,记belong[u]为点u所在SCC的编号。显然有belong[s]!=belong[t](否则s到t有通路,能继续增广)。
      ①对于任意一条满流边(u,v),(u,v)能够出现在某个最小割集中,当且仅当belong[u]!=belong[v];
      ②对于任意一条满流边(u,v),(u,v)必定出现在最小割集中,当且仅当belong[u]==belong[s]且belong[v]==belong[t]。

    细节

      我也不知道为什么犯了若干sb错误= =

    代码

    // bzoj1797
    #include<algorithm>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #include<queue>
    #define LL long long
    #define inf (1ll<<60)
    #define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout)
    using namespace std;
    
    const int maxn=1000010;
    int head[maxn],bel[maxn],low[maxn],dfn[maxn],st[maxn],id[maxn],n,m,S,T,top,scc,cnt=1;
    struct edge {int from,to,next,w;}e[maxn];
    
    namespace Dinic {
    	int d[maxn];
    	bool bfs() {
    		memset(d,-1,sizeof(d));
    		queue<int> q;q.push(S);d[S]=0;
    		while (!q.empty()) {
    			int x=q.front();q.pop();
    			for (int i=head[x];i;i=e[i].next)
    				if (e[i].w && d[e[i].to]<0) d[e[i].to]=d[x]+1,q.push(e[i].to);
    		}
    		return d[T]>0;
    	}
    	int dfs(int x,LL f) {
    		if (x==T || f==0) return f;
    		int w,used=0;
    		for (int i=head[x];i;i=e[i].next) if (e[i].w && d[e[i].to]==d[x]+1) {
    				w=dfs(e[i].to,min(1LL*e[i].w,f-used));
    				used+=w,e[i].w-=w,e[i^1].w+=w;
    				if (used==f) return used;
    			}
    		if (!used) d[x]=-1;
    		return used;
    	}
    	void main() {
    		while (bfs()) dfs(S,inf);
    	}
    }
    
    void link(int u,int v,int w) {
    	e[++cnt]=(edge){u,v,head[u],w};head[u]=cnt;
    	e[++cnt]=(edge){v,u,head[v],0};head[v]=cnt;
    }
    void Tarjan(int x) {
    	low[x]=dfn[x]=++cnt;
    	st[++top]=x;
    	for (int i=head[x];i;i=e[i].next) if (e[i].w) {
    			if (!dfn[e[i].to]) {
    				Tarjan(e[i].to);
    				low[x]=min(low[x],low[e[i].to]);
    			}
    			else if (!bel[e[i].to]) low[x]=min(low[x],dfn[e[i].to]);
    		}
    	if (dfn[x]==low[x]) {
    		scc++;
    		for (;st[top]!=x;top--) bel[st[top]]=scc;
    		bel[st[top--]]=scc;
    	}
    }
    int main() {
    	scanf("%d%d%d%d",&n,&m,&S,&T);
    	for (int u,v,w,i=1;i<=m;i++) {
    		scanf("%d%d%d",&u,&v,&w);
    		id[i]=cnt+1;
    		link(u,v,w);
    	}
    	Dinic::main();cnt=0;
    	for (int i=1;i<=n;i++) if (!dfn[i]) Tarjan(i);
    	for (int i=1;i<=m;i++) {
    		int j=id[i];
    		if (e[j].w!=0 || bel[e[j].from]==bel[e[j].to]) {puts("0 0");continue;}
    		if (bel[e[j].from]==bel[S] && bel[e[j].to]==bel[T]) puts("1 1");
    		else puts("1 0");
    	}
    	return 0;
    }
    
  • 相关阅读:
    数据加密算法详解
    自定义标签+阻尼动画+圆角图片+titleBar随滑动渐隐和显示
    Android MVP Plugin,一键完成MVP结构代码编写
    jquery-validate校验
    C# 后台获取请求来源、文件下载
    【通用邮件发送】C# QQ 网易邮箱
    【asp.net mvc】 扩展 htmlhelper 实现分页
    在MVC5中使用Ninject 依赖注入
    c# txt 文件上传、写入TXT文件、创建图形验证码
    uploadify图片上传配置
  • 原文地址:https://www.cnblogs.com/MashiroSky/p/6617664.html
Copyright © 2020-2023  润新知