版权声明:本文为博主原创文章,未经博主允许必须转载。 https://blog.csdn.net/qq_35950004/article/details/87865308
求可能在最小割的边和一定在最小割中的边。
1.判定边xy是否可能在最小割中 (最小割可行边)
充要条件:
1.满流。
2.在残余网络中找不到x到y的路径。
很好理解,如果还能找到,那么砍了它也没什么用
如果正向弧没流满,那么肯定不是最小割(可以找到另一条更好限制流量的边)
只有满流才能让正向弧等于0,才有不能找到的条件
因此,在算法体现中,他们两个必定只能不属于一个SCC才能在最小割中
2.判定边xy是否必然在最小割中
(最小割必须边)
充要条件:
1.满流。
2.残余网络中源点能到入点,出点能到汇点。
若满流但在残余网络中源点不能到入点或出点不能到汇点,
那么在每条单独路径上一定都存在一条满足最小割可行边的边
(一条容量为0的正向弧阻断路径且没有其他路径),
割掉这条可行边是可以起到同样的阻断效果同时代价更优的。
因此,在算法实现中,只有源点和x属于一个SCC,汇点和y属于一个SCC,才能达到割掉它属于最优解
AC Code:
#include<bits/stdc++.h>
#define maxn 10005
#define maxm 400005
#define inf 0x3f3f3f3f
using namespace std;
int n,m,S,T,x[maxm],y[maxm];
int info[maxn],Prev[maxm],to[maxm],cap[maxm],cnt_e=1;
inline void Node(int u,int v,int c){ Prev[++cnt_e]=info[u],info[u]=cnt_e,to[cnt_e]=v,cap[cnt_e]=c; }
inline void Line(int u,int v,int c){ Node(u,v,c),Node(v,u,0); }
int dis[maxn];
bool BFS()
{
memset(dis,-1,sizeof dis);
static queue<int>q;
q.push(T),dis[T]=0;
for(int now;!q.empty();)
{
now = q.front();q.pop();
for(int i=info[now];i;i=Prev[i])
if(cap[i^1] && dis[to[i]] == -1)
dis[to[i]] = dis[now] + 1 , q.push(to[i]);
}
return dis[S] != -1;
}
int aug(int now,int Max)
{
if(now == T) return Max;
int inc,st=Max;
for(int i=info[now];i && st;i=Prev[i])
if(cap[i] && dis[to[i]] == dis[now] - 1)
{
inc = aug(to[i],min(cap[i],st));
st-=inc,cap[i]-=inc,cap[i^1]+=inc;
}
return Max-st;
}
int dfn[maxn],low[maxn],tot,scc,c[maxn];
stack<int>sta;
void dfs(int now)
{
dfn[now]=low[now]=++tot;
sta.push(now);
for(int i=info[now];i;i=Prev[i])
if(cap[i])
{
if(!dfn[to[i]]) dfs(to[i]),low[now]=min(low[now],low[to[i]]);
else if(!c[to[i]]) low[now] = min(low[now] , dfn[to[i]]);
}
if(low[now] == dfn[now])
{
scc++;
for(int tmp;;)
{
c[tmp=sta.top()] = scc;
sta.pop();
if(tmp == now) break;
}
}
}
int main()
{
scanf("%d%d%d%d",&n,&m,&S,&T);
for(int i=1;i<=m;i++)
{
int c;
scanf("%d%d%d",&x[i],&y[i],&c);
Line(x[i],y[i],c);
}
for(;BFS();) aug(S,inf);
for(int i=1;i<=n;i++)
if(!dfn[i])
dfs(i);
for(int i=1;i<=m;i++)
printf("%d %d\n",c[x[i]]!=c[y[i]] && cap[2*i]==0,(c[x[i]]==c[S] && c[y[i]] == c[T]) && cap[2*i]==0);
}