POJ3204 Ikki's Story I - Road Reconstruction

来源:互联网 发布:mac os 升级老版本 编辑:程序博客网 时间:2024/05/18 16:17

题意:给出一张图,问重建哪几个边能使最大流增大。。

求最小割的割边数,现在原图上跑一遍最大流,然后一个dfs从起点开始沿残余网络染色,同样再用一个dfs从终点染色,两个颜色不能一样,然后再暴力枚举就是,是的条件比较多,要颜色匹配,而且这条边的流量为0,还要注意这条边不能是反向边。

/*************************************************************************> File Name: poj3204.cpp> Author: tjw> Mail: > Created Time: 2014年10月31日 星期五 16时54分40秒 ************************************************************************/#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#include<queue>#include<vector>#include<stack>#include<map>#define ll long long#define ls k<<1#define rs k<<1|1using namespace std;const int MAXN=510;const int MAXE=10010;const int INF=1<<30;struct EDGE{    int v,next;    int cap;}edge[MAXE];int head[MAXN],size;void init(){    memset(head,-1,sizeof(head));    size=0;}void add_edge(int u,int v,int cap){    edge[size].v=v;    edge[size].cap=cap;    edge[size].next=head[u];    head[u]=size++;    edge[size].v=u;    edge[size].cap=0;    edge[size].next=head[v];    head[v]=size++;}int gap[MAXN],dist[MAXN],pre[MAXN],pe[MAXN];int ISAP(int s,int t){    int cur_flow,i,u,neck,temp;    int max_flow;    memset(gap,0,sizeof(gap));    memset(pre,-1,sizeof(pre));    memset(dist,0,sizeof(dist));    for(i=0;i<=t+1;i++)        pe[i]=head[i];    u=s;    max_flow=0;    while(dist[s]<t+1)    {        if(u==t)        {            cur_flow=INF;            for(i=s;i!=t;i=edge[pe[i]].v)            {                if(cur_flow>edge[pe[i]].cap)                {                    cur_flow=edge[pe[i]].cap;                    neck=i;                }            }            for(i=s;i!=t;i=edge[pe[i]].v)            {                temp=pe[i];                edge[temp].cap-=cur_flow;                edge[temp^1].cap+=cur_flow;            }            max_flow+=cur_flow;            u=neck;        }        for(i=pe[u];i!=-1;i=edge[i].next)            if(edge[i].cap&&dist[u]==dist[edge[i].v]+1)                break;        if(i!=-1)        {            pe[u]=i;            pre[edge[i].v]=u;            u=edge[i].v;        }        else        {            if(0==--gap[dist[u]])                break;            pe[u]=head[u];            temp=t+1;            for(i=head[u];i!=-1;i=edge[i].next)            {                if(edge[i].cap)                temp=min(temp,dist[edge[i].v]);            }            dist[u]=temp+1;            ++gap[dist[u]];            if(u!=s)                u=pre[u];        }    }    return max_flow;}int ans;int vis[MAXN];void dfs1(int u){    if(vis[u])        return;    vis[u]=1;    for(int i=head[u];i!=-1;i=edge[i].next)    {        int v=edge[i].v;        if(edge[i].cap!=0)        {            dfs1(v);        }    }}void dfs2(int u){    if(vis[u])        return;    vis[u]=2;    for(int i=head[u];i!=-1;i=edge[i].next)    {        int v=edge[i].v;        if(edge[i^1].cap!=0)            dfs2(v);    }}int main(){    int n,m,i;    while(scanf("%d%d",&n,&m)==2)    {        init();        int u,v,c;        while(m--)        {            scanf("%d%d%d",&u,&v,&c);            add_edge(u,v,c);        }        ans=0;        ISAP(0,n-1);        memset(vis,0,sizeof(vis));        dfs1(0);        dfs2(n-1);        for(u=0;u<n;u++)        {            for(i=head[u];i!=-1;i=edge[i].next)            {                int v=edge[i].v;                if(!(i&1)&&vis[u]==1&&vis[v]==2&&edge[i].cap==0)                    ans++;            }        }        printf("%d\n",ans);    }    return 0;}


0 0
原创粉丝点击