分析:
最小割可行边必需边模板题。
代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <queue>
inline int read(){
int x=0;char ch=getchar();
while(ch<'0'||ch>'9') ch=getchar();
while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
return x;
}
const int MAXN=4005;
const int MAXM=60005;
int n,m,s,t,maxflow,mincut,ecnt=-1,head[MAXN];
int dfn[MAXN],low[MAXN],tot,Stack[MAXN],Top,id[MAXN],tot2;
int dep[MAXN],cur[MAXN];
bool In[MAXN];
std::queue<int> q;
struct Edge{
int to,nxt,cap,fr;
}e[MAXM<<1];
struct Edge2{
int u,v;
}ee[MAXM];
inline void add_edge(int bg,int ed,int ca){
ecnt++;
e[ecnt].to=ed;
e[ecnt].nxt=head[bg];
e[ecnt].cap=ca;
e[ecnt].fr=bg;
head[bg]=ecnt;
}
inline bool bfs(){
memset(dep,0x3f,sizeof dep);
for(int i=1;i<=n;i++) cur[i]=head[i];
while(!q.empty()) q.pop();
dep[s]=1;
q.push(s);
while(!q.empty()){
int u=q.front();q.pop();
for(int i=head[u];i!=-1;i=e[i].nxt){
int ver=e[i].to;
if(dep[ver]>1e9&&e[i].cap){
dep[ver]=dep[u]+1;
q.push(ver);
}
}
}
return dep[t]<1e9;
}
int dfs(int x,int pref){
if(x==t||!pref) return pref;
int flow=0,temp;
for(int& i=cur[x];i!=-1;i=e[i].nxt){
int ver=e[i].to;
if(dep[ver]==dep[x]+1&&(temp=dfs(ver,std::min(pref,e[i].cap)))){
e[i].cap-=temp;
e[i^1].cap+=temp;
pref-=temp;
flow+=temp;
if(!pref) break;
}
}
return flow;
}
inline void dinic(){
while(bfs()) maxflow+=dfs(s,1e9);
}
void tarjan(int x){
dfn[x]=low[x]=++tot;
Stack[++Top]=x;
In[x]=1;
for(int i=head[x];i!=-1;i=e[i].nxt){
if(!e[i].cap) continue;
int ver=e[i].to;
if(!dfn[ver]){
tarjan(ver);
low[x]=std::min(low[x],low[ver]);
}
else if(In[ver])
low[x]=std::min(low[x],low[ver]);
}
if(low[x]==dfn[x]){
tot2++;
while(Stack[Top+1]!=x){
id[Stack[Top]]=tot2;
In[Stack[Top]]=0;
Top--;
}
}
}
int main(){
memset(head,-1,sizeof head);
n=read(),m=read();
s=read(),t=read();
for(int i=1;i<=m;i++){
int u=read(),v=read(),ca=read();
add_edge(u,v,ca);
add_edge(v,u,0);
ee[i].u=u;ee[i].v=v;
}
dinic();
mincut=maxflow;
for(int i=1;i<=n;i++)
if(!dfn[i]) tarjan(i);
for(int i=1;i<=m;i++){
if(e[(i-1)<<1].cap) printf("0 0\n");
else if(id[ee[i].u]==id[ee[i].v]) printf("0 0\n");
else if(id[ee[i].u]!=id[s]||id[ee[i].v]!=id[t]) printf("1 0\n");
else printf("1 1\n");
}
return 0;
}