poj 3204 Ikki's Story I - Road Reconstruction 网络流

来源:互联网 发布:淘宝在哪儿买彩票 编辑:程序博客网 时间:2024/05/20 08:44

求给那些边增加容量能增加总的流量

显然,不是满流的边,增加也没有用,所以要增加容量的是那些满流的边。

做法 求一次最大流 判断有几条边满流且能被源点和汇点搜到

View Code
#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int MAX=100005;const int INF=1000000000;struct{    int v,c,next;}edge[1000000];int E,head[MAX];int gap[MAX],cur[MAX];int pre[MAX],dis[MAX];void add_edge(int s,int t,int c,int cc){    /*加边的时候同时加两条,    一条正的,一条反的,    一般情况下反的容量是0 */    edge[E].v=t; edge[E].c=c;    edge[E].next=head[s];    head[s]=E++;    edge[E].v=s; edge[E].c=cc;    edge[E].next=head[t];    head[t]=E++;}int min(int a,int b){return (a==-1||b<a)?b:a;}int SAP(int s,int t,int n){    memset(gap,0,sizeof(gap));    memset(dis,0,sizeof(dis));    int i;    for(i=0;i<n;i++)cur[i]=head[i];    int u=pre[s]=s,maxflow=0,aug=-1,v;    gap[0]=n;        while(dis[s]<n)    {loop:    for(i=cur[u];i!=-1;i=edge[i].next)        {            v=edge[i].v;            if(edge[i].c>0&&dis[u]==dis[v]+1)            {                aug=min(aug,edge[i].c);                pre[v]=u;                cur[u]=i;                u=v;                if(u==t)                {                    for(u=pre[u];v!=s;v=u,u=pre[u])                    {                        edge[cur[u]].c-=aug;                        edge[cur[u]^1].c+=aug;                    }                    maxflow+=aug;                    aug=-1;                }                goto loop;            }        }        int mindis=n;        for(i=head[u];i!=-1;i=edge[i].next)        {            v=edge[i].v;            if(edge[i].c>0&&dis[v]<mindis)            {                cur[u]=i;                mindis=dis[v];            }        }        if((--gap[dis[u]])==0)break;        gap[dis[u]=mindis+1]++;        u=pre[u];    }    return maxflow;}int n,m;int src,dest;bool vis_src[1000];bool vis_dest[1000];void dfs(int u){    vis_src[u]=true;    for(int i=head[u];i!=-1;i=edge[i].next)    {        int to=edge[i].v;        if(!vis_src[to]&&edge[i].c)                 dfs(to);    }}void dfs2(int u){    vis_dest[u]=1;    for(int i=head[u];i!=-1;i=edge[i].next)    {        int to=edge[i].v;        if(!vis_dest[to]&&edge[i^1].c)            dfs2(to);    }}void solve(){     SAP(0,n-1,n);     memset(vis_src,false,sizeof(vis_src));     dfs(0);     memset(vis_dest,false,sizeof(vis_dest));     dfs2(n-1);     int ans=0;     for(int i=0;i<E;i+=2)     {         if(!edge[i].c&&vis_src[edge[i^1].v]&&vis_dest[edge[i].v])             ans++;     }     printf("%d\n",ans);}int main(){    int i,j,a,b,c;    while(scanf("%d%d",&n,&m)!=EOF)    {        memset(head,-1,sizeof(head));        E=0;        for(i=0;i<m;i++)        {            scanf("%d%d%d",&a,&b,&c);            add_edge(a,b,c,0);        }        solve();    }        return 0;}