B – Internship (网络流割边)

  • 2019-02-08
  • 0
  • 0

题目链接:https://cn.vjudge.net/contest/281961#problem/B

题意:有n个点,m个中转站,l(艾欧)条边,0是接受点,输出增大这条边的容量可以增大图的流量的边的id

思路:割边模板。先跑一边最大流,从s开始遍历一遍,到达的点标记为1,从t利用反向边遍历一遍,到达的点标记为2,如果有一条边的u标记为1,v标记为2,那么这条边就是割边。

代码:

#include <bits/stdc++.h>

using namespace std;

const int maxn=1005;
const int inf=0x3f3f3f3f;
struct node
{
    int to,w,next;
}e[maxn*10];
struct nodee
{
    int u,v,w;
}edge[maxn*10];
int n,m,l,s,t,maxflow;
int head[maxn],cnt,cur[maxn],dep[maxn];
int vis[maxn];

void init()
{
    memset(head,-1,sizeof(head));
    cnt=0;
    maxflow=0;
    memset(vis,0,sizeof(vis));
}

void add(int u,int v,int w)
{
    e[cnt]=node{v,w,head[u]};
    head[u]=cnt++;
}

bool bfs()
{
    for(int i=0;i<=n+m+1;i++)
    {
        cur[i]=head[i];
    }
    memset(dep,inf,sizeof(dep));
    queue<int>q;
    q.push(s);
    dep[s]=0;
    while(!q.empty())
    {
        int x=q.front();
        q.pop();
        for(int i=head[x];i!=-1;i=e[i].next)
        {
            int to=e[i].to,w=e[i].w;
            if(w>0&&dep[to]>=inf)
            {
                dep[to]=dep[x]+1;
                q.push(to);
            }
        }
    }
    if(dep[t]<inf)return true;
    else return false;
}

int dfs(int x,int limit)
{
    if(x==t||!limit)return limit;
    int flow=0;
    for(int i=cur[x];i!=-1;i=e[i].next)
    {
        cur[x]=i;
        int to=e[i].to,w=e[i].w;
        if(dep[to]==dep[x]+1)
        {
            int a=dfs(to,min(limit,w));
            limit-=a;
            flow+=a;
            e[i].w-=a;
            e[i^1].w+=a;
        }
        if(!limit)break;
    }
    return flow;
}

void dinic()
{
    while(bfs())
    {
        maxflow+=dfs(s,inf);
    }
}

void dfs_s(int x)
{
    vis[x]=1;
    for(int i=head[x];i!=-1;i=e[i].next)
    {
        int to=e[i].to,w=e[i].w;
        if(w>0&&!vis[to])
        {
            dfs_s(to);
        }
    }
}

void dfs_t(int x)
{
    vis[x]=2;
    for(int i=head[x];i!=-1;i=e[i].next)
    {
        int to=e[i].to,w=e[i].w,ww=e[i^1].w;
        if(w>0&&ww>0&&!vis[to])
        {
            dfs_t(to);
        }
    }
}

int main()
{
    ios::sync_with_stdio(false);
    while(cin>>n>>m>>l)
    {
        init();
        if(!n)break;
        s=n+m+1;
        t=0;
        for(int i=1;i<=n;i++)
        {
            add(s,i,inf);
            add(i,s,0);
        }
        for(int i=1;i<=l;i++)
        {
            int a,b,c;
            cin>>a>>b>>c;
            add(a,b,c);
            add(b,a,0);
            edge[i]=nodee{a,b,c};
        }
        dinic();
        //cout<<maxflow<<endl;
        dfs_s(s);
        dfs_t(t);
        int flag=1;
        for(int i=1;i<=l;i++)
        {
            int u=edge[i].u,v=edge[i].v;
            if(vis[u]==1&&vis[v]==2)
            {
                if(!flag)cout<<" ";
                cout<<i;
                flag=0;
            }
        }
        cout<<endl;
    }
    return 0;
}

评论

还没有任何评论,你来说两句吧