继续填坑了,啦啦啦
这道题本来是准备枚举每个边,暂时去除它,但发现时间会爆炸的
于是决定另辟蹊径
于是这篇题解就应运而生
首先还是网络流跑一边 毕竟题目叫最小割嘛,给个面子
然后跑一边tarjan对满流的边处理掉,即不相连
之后对每条边进行判断,如果当前的边流量为0并且始末点不在一个集合,那么就满足第一个条件了
若始末点于源点汇点为同一个集合,那么就满足第二个条件了
不然的话直接输出0 0 即可
#include<bits/stdc++.h> using namespace std; const int N=4e5+7; const int INF=0x7f7f7f; int m,n,k,s,t,cnt=1,mx,ans,idx; int dep[N],head[N],dfn[N],low[N],color[N],sum[N],num; bool vis[N]; stack<int> st; struct edge { int nx,to,flow,from; } e[N]; void add_edge(int a,int b,int flow) { cnt++;e[cnt].flow=flow;e[cnt].nx=head[a];e[cnt].to=b;e[cnt].from=a;head[a]=cnt; cnt++;e[cnt].flow=0;e[cnt].nx=head[b];e[cnt].to=a;e[cnt].from=b;head[b]=cnt; } bool bfs(int s,int t) { memset(dep,0,sizeof(dep));queue<int> que; dep[s]=1;que.push(s); while (!que.empty()) { int x=que.front();que.pop(); for (int i=head[x];i;i=e[i].nx) { int y=e[i].to; if (dep[y]==0&&e[i].flow) { dep[y]=dep[x]+1; que.push(y); } } } if (dep[t]==0) return false; else return true; } void paint(int x) { st.pop(); color[x]=num; sum[num]++; vis[x]=false; } void tarjan(int x) { dfn[x]=low[x]=++idx; st.push(x);vis[x]=true; for (int i=head[x];i;i=e[i].nx) { if (e[i].flow==0) continue; int y=e[i].to; if (!dfn[y]) { tarjan(y); low[x]=min(low[x],low[y]); } else if (vis[y]) low[x]=min(low[x],dfn[y]); } if (dfn[x]==low[x]) { num++; while (st.top()!=x) { int t=st.top(); paint(t); } paint(x); } } int dfs(int x,int limit,int t) { if (x==t) return limit; int used=0; for (int i=head[x];i;i=e[i].nx) { int y=e[i].to; if (dep[y]==dep[x]+1&&e[i].flow) { int di=dfs(y,min(limit-used,e[i].flow),t); if (di>0) { e[i].flow-=di; e[i^1].flow+=di; used+=di; if (used==limit) return limit; } } } if (!used) dep[x]=-2; return used; } void dinic(int s,int t) { while (bfs(s,t)) ans+=dfs(s,INF,t); } int main() { scanf("%d%d%d%d",&n,&m,&s,&t); for (int i=1;i<=m;i++) { int x,y,z; scanf("%d%d%d",&x,&y,&z); add_edge(x,y,z); } dinic(s,t); mx=ans; for (int i=1;i<=n;i++) if (!color[i]) tarjan(i); for (int i=2;i<cnt;i+=2) { int x=e[i].from,y=e[i].to; if (color[x]!=color[y]&&e[i].flow==0) { printf("1 "); if (color[x]==color[s]&&color[y]==color[t]) printf("1"); else printf("0"); } else printf("0 0"); printf(" "); } return 0; }