poj 3204 网络流

来源:互联网 发布:托福报名 知乎 编辑:程序博客网 时间:2024/05/18 13:09

用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;}
 


原创粉丝点击