用dinic求最大流
然后枚举残余网络中,正边容量为0的边,容量加1,若能makelevel,ans++;
#include <iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
const int inf=1<<30;
const int maxn=1011;
struct node
{
int to,w,next;
}e[20001];
int head[maxn],lon;
int edgeini(int n)
{
memset(head,-1,sizeof(head));
lon=-1;
}
int edgemake(int from,int to,int w)
{
e[++lon].to=to;
e[lon].w=w;
e[lon].next=head[from];
head[from]=lon;
}
int level[maxn];
int makelevel(int s,int t)
{
memset(level,0,sizeof(level));
level[s]=1;
int que[maxn];
int top=0;
que[++top]=s;
for(int i=1;i<=top;i++)
{
int u=que[i];
if(u==t) return(1);
for(int k=head[u];k!=-1;k=e[k].next)
if(!level[e[k].to]&&e[k].w)
{
level[e[k].to]=level[u]+1;
que[++top]=e[k].to;
}
}
return(0);
}
int dfs(int now,int maxf,int t)
{
if(now==t)return(maxf);
int ret=0;
for(int k=head[now];k!=-1;k=e[k].next)
if(e[k].w&&level[e[k].to]==level[now]+1)
{
int f=dfs(e[k].to,min(maxf-ret,e[k].w),t);
e[k].w-=f;
e[k^1].w+=f;
ret+=f;
if(ret==maxf) return(ret);
}
return(ret);
}
int dinic(int s,int t)
{
int ans=0;
while(makelevel(s,t)) {ans+=dfs(s,inf,t);}
return(ans);
}
int main()
{
// freopen("in.txt","r",stdin);
int n,m;
scanf("%d%d",&n,&m);
edgeini(n);
for(int i=1;i<=m;i++)
{
int from,to,w;
scanf("%d %d %d",&from,&to,&w);
edgemake(from,to,w);
edgemake(to,from,0);
}
int sum=dinic(0,n-1);
// printf("%d\n",sum);
int ans=0;
for(int k=0;k<=lon;k+=2)
if(e[k].w==0)
{
e[k].w+=1;
if(makelevel(0,n-1)) ans++;
e[k].w-=1;
}
printf("%d\n",ans);
return 0;
}