现在的位置: 首页 > 综合 > 正文

poj 3204 Ikki’s Story I – Road Reconstruction 网络流

2013年01月30日 ⁄ 综合 ⁄ 共 1827字 ⁄ 字号 评论关闭

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

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

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

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

抱歉!评论已关闭.