uva 11248 网络流 【扩一条边的容量至某一指定值】

来源:互联网 发布:java重载规则 编辑:程序博客网 时间:2024/06/01 07:40

【求出最大流后,给一条边扩容后,希望最大流能提升至某一指定值】的若干优化:

1.只扩最小割的边: 错误(即使最小割唯一)

2.只扩flow==cap的边:正确


#include <cstdio>#include <cstring>#include <algorithm>#include <iostream>#include <cstdlib>#include <cmath>#include <queue>#include <vector>#include <map>#define pb push_back#define mp make_pair#define eps 1e-9#define zero(x) (fabs(x)<eps)#define pi acos(-1.0)#define f1 first#define f2 second#define lson l,mid,rt<<1#define rson mid+1,r,rt<<1|1#define initial 1,n,1const int inf=2000000010;//const long long INF=1LL<<50;using namespace std;typedef long long LL;typedef pair <int, int> PII;template<typename X> inline bool minimize(X&p,X q){if(p<=q)return 0;p=q;return 1;}template<typename X> inline bool maximize(X&p,X q){if(p>=q)return 0;p=q;return 1;}const int MAXN=111;int n,m,cc,yy;int b[10005][3];struct ISAP{   struct Edge    {        int from,to,cap,flow;        Edge(){}        Edge(int a,int b,int c,int d):from(a),to(b),cap(c),flow(d){}        bool operator<(const Edge &oth)const            {                if (from!=oth.from) return from<oth.from;                return to<oth.to;            }    };    int n,m,s,t;//结点数,边数(含反向弧),源点,汇点    vector<Edge> edges,pp,anss;//边表,edges[e]&edges[e^1]互为反向弧    vector<int> G[MAXN];//邻接表,G[i][j]表示结点i的第j条边在e数组中的序号    bool vis[MAXN];//BFS使用    int d[MAXN];//从起点到i的距离    int cur[MAXN];//当前弧下标    int p[MAXN];//可增广路上的上一条弧    int num[MAXN];//距离标号计数    void AddEdge(int from,int to,int cap)//重边不影响    {   //printf("%d  %d %d\n",from,to,cap);        edges.push_back(Edge(from,to,cap,0));        edges.push_back(Edge(to,from,0,0));//容量为0,表示反向弧        m=edges.size();        G[from].push_back(m-2);        G[to].push_back(m-1);    }    void init(int n)    {        this->n=n;        for(int i=0;i<n;++i) G[i].clear();        edges.clear();    }    void BFS()//反向    {   for (int i=0;i<n;i++)            d[i]=n+10; //!!!        memset(vis,0,sizeof(vis));        queue<int> Q;        Q.push(t);        d[t]=0;        vis[t]=1;        while(!Q.empty())        {            int x=Q.front();            Q.pop();            for(int i=0; i<G[x].size(); ++i)            {                Edge& e=edges[G[x][i]^1];                if(!vis[e.from]&&e.cap>e.flow)                {                    vis[e.from]=1;                    d[e.from]=d[x]+1;                    Q.push(e.from);                }            }        }    }    int Augment()    {        int x=t,a=inf;        while(x!=s)        {            Edge& e=edges[p[x]];            a=min(a,e.cap-e.flow);            x=edges[p[x]].from;        }        x=t;        while(x!=s)        {            edges[p[x]].flow+=a;            edges[p[x]^1].flow-=a;            x=edges[p[x]].from;        }        return a;    }    int Maxflow(int s,int t)//结点数    {        this->s=s,this->t=t;        int flow=0;        BFS();        memset(num,0,sizeof(num));        for(int i=0;i<n;++i) if (d[i]!=n+10)++num[d[i]];//!!!        int x=s;        memset(cur,0,sizeof(cur));        while(d[s]<n)        {            if(x==t)            {                flow+=Augment();                if (flow+yy>=cc) return flow;                x=s;            }            int ok=0;            for(int i=cur[x];i<G[x].size();++i)            {                Edge& e=edges[G[x][i]];                if(e.cap>e.flow&&d[x]==d[e.to]+1)//Advance                {                    ok=1;                    p[e.to]=G[x][i];                    cur[x]=i;                    x=e.to;                    break;                }            }            if(!ok)//Retreat            {                int m=n-1;                for(int i=0;i<G[x].size();++i)                {                    Edge& e=edges[G[x][i]];                    if(e.cap>e.flow) m=min(m,d[e.to]);                }                if(--num[d[x]]==0) break;//gap优化                num[d[x]=m+1]++;                cur[x]=0;                if(x!=s) x=edges[p[x]].from;            }        }        return flow;    }    void dfs1(int x)    {   vis[x]=1;        for(int i=0;i<G[x].size();++i)                {                    Edge& e=edges[G[x][i]];                    if(e.flow<e.cap&&!vis[e.to]) dfs1(e.to);                }    }    void dfs2(int x)    {   vis2[x]=1;        for(int i=0;i<g[x].size();++i)               if(!vis2[g[x][i]]) dfs2(g[x][i]);    }    vector<int> g[MAXN];    bool vis2[MAXN];    void solve()    {   for (int i=0;i<n;i++) g[i].clear();        for (int i=0;i<edges.size();i++)            if (edges[i].flow<edges[i].cap)                g[edges[i].to].push_back(edges[i].from);       memset(vis,0,sizeof(vis));       memset(vis2,0,sizeof(vis2));       dfs1(s);       dfs2(t);       pp.clear(); anss.clear();       for (int i=0;i<edges.size();i++)pp.pb(edges[i]);       for (int i=0;i<pp.size();i+=2)            if (pp[i].flow==pp[i].cap)                {                    edges.clear();                    for (int ii=0;ii<pp.size();ii++)edges.pb(pp[ii]);                    edges[i].cap=cc;                    int tmp=Maxflow(s,t);                    if (tmp+yy>=cc) anss.pb(edges[i]);                }    }}it;void doit(){    it.init(n);    for (int i=1;i<=m;i++)        {scanf("%d%d%d",&b[i][0],&b[i][1],&b[i][2]);         b[i][0]--;b[i][1]--;         it.AddEdge(b[i][0],b[i][1],b[i][2]);        }    yy=0;    yy=it.Maxflow(0,n-1);    if (yy>=cc){printf("possible\n");return;}    it.solve();    sort(it.anss.begin(),it.anss.end());    if (it.anss.size()==0)  {printf("not possible\n");return;}    printf("possible option:");    bool have=0;    for (int i=0;i<it.anss.size();i++)        {   if (have) printf(",");            printf("(%d,%d)",it.anss[i].from+1,it.anss[i].to+1);            have=1;        }    printf("\n");}int main(){   int id=0;    //freopen("in.txt","r",stdin);    while (scanf("%d%d%d",&n,&m,&cc),n||m||cc)        {printf("Case %d: ",++id);         doit();        }}/*4 4 51 2 51 3 52 4 53 4 54 4 53 4 11 2 11 3 52 4 54 4 51 2 11 3 12 4 13 4 10 0 0*/


0 0
原创粉丝点击